aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/mfd/wm8994/pdata.h12
-rw-r--r--include/linux/mfd/wm8994/registers.h2
-rw-r--r--include/sound/control.h2
-rw-r--r--include/sound/cs4271.h1
-rw-r--r--include/sound/soc.h61
-rw-r--r--include/sound/tlv320aic32x4.h31
-rw-r--r--include/sound/wm8903.h10
-rw-r--r--include/sound/wm9081.h9
-rw-r--r--sound/core/control.c46
-rw-r--r--sound/soc/codecs/Kconfig22
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ak4104.c1
-rw-r--r--sound/soc/codecs/cs4270.c4
-rw-r--r--sound/soc/codecs/cs4271.c112
-rw-r--r--sound/soc/codecs/cx20442.c2
-rw-r--r--sound/soc/codecs/dfbmcs320.c72
-rw-r--r--sound/soc/codecs/lm4857.c276
-rw-r--r--sound/soc/codecs/max9850.c389
-rw-r--r--sound/soc/codecs/max9850.h38
-rw-r--r--sound/soc/codecs/sgtl5000.c1513
-rw-r--r--sound/soc/codecs/sgtl5000.h400
-rw-r--r--sound/soc/codecs/sn95031.c239
-rw-r--r--sound/soc/codecs/sn95031.h33
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c794
-rw-r--r--sound/soc/codecs/tlv320aic32x4.h143
-rw-r--r--sound/soc/codecs/tlv320dac33.c1
-rw-r--r--sound/soc/codecs/wm2000.c14
-rw-r--r--sound/soc/codecs/wm8753.c296
-rw-r--r--sound/soc/codecs/wm8903.c514
-rw-r--r--sound/soc/codecs/wm8903.h10
-rw-r--r--sound/soc/codecs/wm8978.c17
-rw-r--r--sound/soc/codecs/wm8994-tables.c12
-rw-r--r--sound/soc/codecs/wm8994.c386
-rw-r--r--sound/soc/codecs/wm8994.h2
-rw-r--r--sound/soc/codecs/wm9081.c83
-rw-r--r--sound/soc/codecs/wm_hubs.c6
-rw-r--r--sound/soc/davinci/davinci-evm.c18
-rw-r--r--sound/soc/davinci/davinci-i2s.c28
-rw-r--r--sound/soc/davinci/davinci-mcasp.c29
-rw-r--r--sound/soc/ep93xx/edb93xx.c16
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c1
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c31
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/imx/Kconfig13
-rw-r--r--sound/soc/imx/Makefile2
-rw-r--r--sound/soc/imx/eukrea-tlv320.c5
-rw-r--r--sound/soc/imx/imx-ssi.c5
-rw-r--r--sound/soc/imx/mx27vis-aic32x4.c137
-rw-r--r--sound/soc/mid-x86/Kconfig2
-rw-r--r--sound/soc/mid-x86/mfld_machine.c209
-rw-r--r--sound/soc/mid-x86/sst_platform.c9
-rw-r--r--sound/soc/pxa/e740_wm9705.c4
-rw-r--r--sound/soc/pxa/e750_wm9705.c4
-rw-r--r--sound/soc/pxa/e800_wm9712.c4
-rw-r--r--sound/soc/pxa/em-x270.c4
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c4
-rw-r--r--sound/soc/pxa/palm27x.c4
-rw-r--r--sound/soc/pxa/raumfeld.c16
-rw-r--r--sound/soc/pxa/tosa.c4
-rw-r--r--sound/soc/pxa/z2.c7
-rw-r--r--sound/soc/pxa/zylonite.c4
-rw-r--r--sound/soc/samsung/Kconfig19
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/dma.c2
-rw-r--r--sound/soc/samsung/lm4857.h32
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c494
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c634
-rw-r--r--sound/soc/soc-cache.c25
-rw-r--r--sound/soc/soc-core.c284
-rw-r--r--sound/soc/soc-dapm.c217
-rw-r--r--sound/soc/soc-jack.c58
-rw-r--r--sound/soc/tegra/Makefile3
-rw-r--r--sound/soc/tegra/harmony.c103
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c6
-rw-r--r--sound/soc/tegra/tegra_das.c1
-rw-r--r--sound/soc/tegra/tegra_i2s.c1
-rw-r--r--sound/soc/tegra/tegra_pcm.c9
77 files changed, 6199 insertions, 1820 deletions
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 9eab263658be..466b1c777aff 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -103,13 +103,21 @@ struct wm8994_pdata {
103 unsigned int lineout1fb:1; 103 unsigned int lineout1fb:1;
104 unsigned int lineout2fb:1; 104 unsigned int lineout2fb:1;
105 105
106 /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */ 106 /* IRQ for microphone detection if brought out directly as a
107 * signal.
108 */
109 int micdet_irq;
110
111 /* WM8994 microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
107 unsigned int micbias1_lvl:1; 112 unsigned int micbias1_lvl:1;
108 unsigned int micbias2_lvl:1; 113 unsigned int micbias2_lvl:1;
109 114
110 /* Jack detect threashold levels, see datasheet for values */ 115 /* WM8994 jack detect threashold levels, see datasheet for values */
111 unsigned int jd_scthr:2; 116 unsigned int jd_scthr:2;
112 unsigned int jd_thr:2; 117 unsigned int jd_thr:2;
118
119 /* WM8958 microphone bias configuration */
120 int micbias[2];
113}; 121};
114 122
115#endif 123#endif
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index be072faec6f0..f3ee84284670 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -63,6 +63,8 @@
63#define WM8994_MICBIAS 0x3A 63#define WM8994_MICBIAS 0x3A
64#define WM8994_LDO_1 0x3B 64#define WM8994_LDO_1 0x3B
65#define WM8994_LDO_2 0x3C 65#define WM8994_LDO_2 0x3C
66#define WM8958_MICBIAS1 0x3D
67#define WM8958_MICBIAS2 0x3E
66#define WM8994_CHARGE_PUMP_1 0x4C 68#define WM8994_CHARGE_PUMP_1 0x4C
67#define WM8958_CHARGE_PUMP_2 0x4D 69#define WM8958_CHARGE_PUMP_2 0x4D
68#define WM8994_CLASS_W_1 0x51 70#define WM8994_CLASS_W_1 0x51
diff --git a/include/sound/control.h b/include/sound/control.h
index 7715e6f00d38..e67db2869360 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -115,6 +115,8 @@ int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
115int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol); 115int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
116int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); 116int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
117int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); 117int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
118int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
119 int active);
118struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid); 120struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
119struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id); 121struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
120 122
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h
index 16f8d325d3dc..50a059e7d116 100644
--- a/include/sound/cs4271.h
+++ b/include/sound/cs4271.h
@@ -19,7 +19,6 @@
19 19
20struct cs4271_platform_data { 20struct cs4271_platform_data {
21 int gpio_nreset; /* GPIO driving Reset pin, if any */ 21 int gpio_nreset; /* GPIO driving Reset pin, if any */
22 int gpio_disable; /* GPIO that disable serial bus, if any */
23}; 22};
24 23
25#endif /* __CS4271_H */ 24#endif /* __CS4271_H */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 4b6c0a8c332f..bfa4836ea107 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -234,6 +234,7 @@ struct snd_soc_codec;
234struct snd_soc_codec_driver; 234struct snd_soc_codec_driver;
235struct soc_enum; 235struct soc_enum;
236struct snd_soc_jack; 236struct snd_soc_jack;
237struct snd_soc_jack_zone;
237struct snd_soc_jack_pin; 238struct snd_soc_jack_pin;
238struct snd_soc_cache_ops; 239struct snd_soc_cache_ops;
239#include <sound/soc-dapm.h> 240#include <sound/soc-dapm.h>
@@ -258,6 +259,11 @@ enum snd_soc_compress_type {
258 SND_SOC_RBTREE_COMPRESSION 259 SND_SOC_RBTREE_COMPRESSION
259}; 260};
260 261
262int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
263 unsigned int freq, int dir);
264int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
265 unsigned int freq_in, unsigned int freq_out);
266
261int snd_soc_register_card(struct snd_soc_card *card); 267int snd_soc_register_card(struct snd_soc_card *card);
262int snd_soc_unregister_card(struct snd_soc_card *card); 268int snd_soc_unregister_card(struct snd_soc_card *card);
263int snd_soc_suspend(struct device *dev); 269int snd_soc_suspend(struct device *dev);
@@ -307,6 +313,9 @@ void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
307 struct notifier_block *nb); 313 struct notifier_block *nb);
308void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack, 314void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
309 struct notifier_block *nb); 315 struct notifier_block *nb);
316int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
317 struct snd_soc_jack_zone *zones);
318int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage);
310#ifdef CONFIG_GPIOLIB 319#ifdef CONFIG_GPIOLIB
311int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, 320int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
312 struct snd_soc_jack_gpio *gpios); 321 struct snd_soc_jack_gpio *gpios);
@@ -331,7 +340,8 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
331 *Controls 340 *Controls
332 */ 341 */
333struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 342struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
334 void *data, char *long_name); 343 void *data, char *long_name,
344 const char *prefix);
335int snd_soc_add_controls(struct snd_soc_codec *codec, 345int snd_soc_add_controls(struct snd_soc_codec *codec,
336 const struct snd_kcontrol_new *controls, int num_controls); 346 const struct snd_kcontrol_new *controls, int num_controls);
337int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, 347int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
@@ -407,6 +417,24 @@ struct snd_soc_jack_pin {
407}; 417};
408 418
409/** 419/**
420 * struct snd_soc_jack_zone - Describes voltage zones of jack detection
421 *
422 * @min_mv: start voltage in mv
423 * @max_mv: end voltage in mv
424 * @jack_type: type of jack that is expected for this voltage
425 * @debounce_time: debounce_time for jack, codec driver should wait for this
426 * duration before reading the adc for voltages
427 * @:list: list container
428 */
429struct snd_soc_jack_zone {
430 unsigned int min_mv;
431 unsigned int max_mv;
432 unsigned int jack_type;
433 unsigned int debounce_time;
434 struct list_head list;
435};
436
437/**
410 * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection 438 * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection
411 * 439 *
412 * @gpio: gpio number 440 * @gpio: gpio number
@@ -414,6 +442,10 @@ struct snd_soc_jack_pin {
414 * @report: value to report when jack detected 442 * @report: value to report when jack detected
415 * @invert: report presence in low state 443 * @invert: report presence in low state
416 * @debouce_time: debouce time in ms 444 * @debouce_time: debouce time in ms
445 * @wake: enable as wake source
446 * @jack_status_check: callback function which overrides the detection
447 * to provide more complex checks (eg, reading an
448 * ADC).
417 */ 449 */
418#ifdef CONFIG_GPIOLIB 450#ifdef CONFIG_GPIOLIB
419struct snd_soc_jack_gpio { 451struct snd_soc_jack_gpio {
@@ -422,6 +454,8 @@ struct snd_soc_jack_gpio {
422 int report; 454 int report;
423 int invert; 455 int invert;
424 int debounce_time; 456 int debounce_time;
457 bool wake;
458
425 struct snd_soc_jack *jack; 459 struct snd_soc_jack *jack;
426 struct delayed_work work; 460 struct delayed_work work;
427 461
@@ -435,6 +469,7 @@ struct snd_soc_jack {
435 struct list_head pins; 469 struct list_head pins;
436 int status; 470 int status;
437 struct blocking_notifier_head notifier; 471 struct blocking_notifier_head notifier;
472 struct list_head jack_zones;
438}; 473};
439 474
440/* SoC PCM stream information */ 475/* SoC PCM stream information */
@@ -533,6 +568,18 @@ struct snd_soc_codec_driver {
533 pm_message_t state); 568 pm_message_t state);
534 int (*resume)(struct snd_soc_codec *); 569 int (*resume)(struct snd_soc_codec *);
535 570
571 /* Default DAPM setup, added after probe() is run */
572 const struct snd_soc_dapm_widget *dapm_widgets;
573 int num_dapm_widgets;
574 const struct snd_soc_dapm_route *dapm_routes;
575 int num_dapm_routes;
576
577 /* codec wide operations */
578 int (*set_sysclk)(struct snd_soc_codec *codec,
579 int clk_id, unsigned int freq, int dir);
580 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
581 unsigned int freq_in, unsigned int freq_out);
582
536 /* codec IO */ 583 /* codec IO */
537 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 584 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
538 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); 585 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
@@ -653,6 +700,7 @@ struct snd_soc_card {
653 bool instantiated; 700 bool instantiated;
654 701
655 int (*probe)(struct snd_soc_card *card); 702 int (*probe)(struct snd_soc_card *card);
703 int (*late_probe)(struct snd_soc_card *card);
656 int (*remove)(struct snd_soc_card *card); 704 int (*remove)(struct snd_soc_card *card);
657 705
658 /* the pre and post PM functions are used to do any PM work before and 706 /* the pre and post PM functions are used to do any PM work before and
@@ -689,6 +737,14 @@ struct snd_soc_card {
689 struct snd_soc_pcm_runtime *rtd_aux; 737 struct snd_soc_pcm_runtime *rtd_aux;
690 int num_aux_rtd; 738 int num_aux_rtd;
691 739
740 /*
741 * Card-specific routes and widgets.
742 */
743 struct snd_soc_dapm_widget *dapm_widgets;
744 int num_dapm_widgets;
745 struct snd_soc_dapm_route *dapm_routes;
746 int num_dapm_routes;
747
692 struct work_struct deferred_resume_work; 748 struct work_struct deferred_resume_work;
693 749
694 /* lists of probed devices belonging to this card */ 750 /* lists of probed devices belonging to this card */
@@ -700,6 +756,9 @@ struct snd_soc_card {
700 struct list_head paths; 756 struct list_head paths;
701 struct list_head dapm_list; 757 struct list_head dapm_list;
702 758
759 /* Generic DAPM context for the card */
760 struct snd_soc_dapm_context dapm;
761
703#ifdef CONFIG_DEBUG_FS 762#ifdef CONFIG_DEBUG_FS
704 struct dentry *debugfs_card_root; 763 struct dentry *debugfs_card_root;
705 struct dentry *debugfs_pop_time; 764 struct dentry *debugfs_pop_time;
diff --git a/include/sound/tlv320aic32x4.h b/include/sound/tlv320aic32x4.h
new file mode 100644
index 000000000000..c009f70b4029
--- /dev/null
+++ b/include/sound/tlv320aic32x4.h
@@ -0,0 +1,31 @@
1/*
2 * tlv320aic32x4.h -- TLV320AIC32X4 Soc Audio driver platform data
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.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 _AIC32X4_PDATA_H
14#define _AIC32X4_PDATA_H
15
16#define AIC32X4_PWR_MICBIAS_2075_LDOIN 0x00000001
17#define AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE 0x00000002
18#define AIC32X4_PWR_AIC32X4_LDO_ENABLE 0x00000004
19#define AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 0x00000008
20#define AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED 0x00000010
21
22#define AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K 0x00000001
23#define AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K 0x00000002
24
25struct aic32x4_pdata {
26 u32 power_cfg;
27 u32 micpga_routing;
28 bool swapdacs;
29};
30
31#endif
diff --git a/include/sound/wm8903.h b/include/sound/wm8903.h
index 86172cf4339f..cf7ccb76a8de 100644
--- a/include/sound/wm8903.h
+++ b/include/sound/wm8903.h
@@ -17,13 +17,9 @@
17/* 17/*
18 * R6 (0x06) - Mic Bias Control 0 18 * R6 (0x06) - Mic Bias Control 0
19 */ 19 */
20#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */ 20#define WM8903_MICDET_THR_MASK 0x0030 /* MICDET_THR - [5:4] */
21#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */ 21#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [5:4] */
22#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */ 22#define WM8903_MICDET_THR_WIDTH 2 /* MICDET_THR - [5:4] */
23#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
24#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
25#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
26#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
27#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */ 23#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
28#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */ 24#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
29#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */ 25#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
diff --git a/include/sound/wm9081.h b/include/sound/wm9081.h
index e173ddbf6bd4..f34b0b1716d8 100644
--- a/include/sound/wm9081.h
+++ b/include/sound/wm9081.h
@@ -17,9 +17,12 @@ struct wm9081_retune_mobile_setting {
17 u16 config[20]; 17 u16 config[20];
18}; 18};
19 19
20struct wm9081_retune_mobile_config { 20struct wm9081_pdata {
21 struct wm9081_retune_mobile_setting *configs; 21 bool irq_high; /* IRQ is active high */
22 int num_configs; 22 bool irq_cmos; /* IRQ is in CMOS mode */
23
24 struct wm9081_retune_mobile_setting *retune_configs;
25 int num_retune_configs;
23}; 26};
24 27
25#endif 28#endif
diff --git a/sound/core/control.c b/sound/core/control.c
index 9ce00ed20fba..db51e4e64984 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -466,6 +466,52 @@ error:
466} 466}
467 467
468/** 468/**
469 * snd_ctl_activate_id - activate/inactivate the control of the given id
470 * @card: the card instance
471 * @id: the control id to activate/inactivate
472 * @active: non-zero to activate
473 *
474 * Finds the control instance with the given id, and activate or
475 * inactivate the control together with notification, if changed.
476 *
477 * Returns 0 if unchanged, 1 if changed, or a negative error code on failure.
478 */
479int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
480 int active)
481{
482 struct snd_kcontrol *kctl;
483 struct snd_kcontrol_volatile *vd;
484 unsigned int index_offset;
485 int ret;
486
487 down_write(&card->controls_rwsem);
488 kctl = snd_ctl_find_id(card, id);
489 if (kctl == NULL) {
490 ret = -ENOENT;
491 goto unlock;
492 }
493 index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
494 vd = &kctl->vd[index_offset];
495 ret = 0;
496 if (active) {
497 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE))
498 goto unlock;
499 vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
500 } else {
501 if (vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)
502 goto unlock;
503 vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
504 }
505 ret = 1;
506 unlock:
507 up_write(&card->controls_rwsem);
508 if (ret > 0)
509 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, id);
510 return ret;
511}
512EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
513
514/**
469 * snd_ctl_rename_id - replace the id of a control on the card 515 * snd_ctl_rename_id - replace the id of a control on the card
470 * @card: the card instance 516 * @card: the card instance
471 * @src_id: the old id 517 * @src_id: the old id
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index e239345a4d5d..d63c1754e05f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -29,16 +29,21 @@ config SND_SOC_ALL_CODECS
29 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 29 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
30 select SND_SOC_CX20442 30 select SND_SOC_CX20442
31 select SND_SOC_DA7210 if I2C 31 select SND_SOC_DA7210 if I2C
32 select SND_SOC_DFBMCS320
32 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
34 select SND_SOC_LM4857 if I2C
33 select SND_SOC_MAX98088 if I2C 35 select SND_SOC_MAX98088 if I2C
36 select SND_SOC_MAX9850 if I2C
34 select SND_SOC_MAX9877 if I2C 37 select SND_SOC_MAX9877 if I2C
35 select SND_SOC_PCM3008 38 select SND_SOC_PCM3008
39 select SND_SOC_SGTL5000 if I2C
36 select SND_SOC_SN95031 if INTEL_SCU_IPC 40 select SND_SOC_SN95031 if INTEL_SCU_IPC
37 select SND_SOC_SPDIF 41 select SND_SOC_SPDIF
38 select SND_SOC_SSM2602 if I2C 42 select SND_SOC_SSM2602 if I2C
39 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 43 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
40 select SND_SOC_TLV320AIC23 if I2C 44 select SND_SOC_TLV320AIC23 if I2C
41 select SND_SOC_TLV320AIC26 if SPI_MASTER 45 select SND_SOC_TLV320AIC26 if SPI_MASTER
46 select SND_SOC_TVL320AIC32X4 if I2C
42 select SND_SOC_TLV320AIC3X if I2C 47 select SND_SOC_TLV320AIC3X if I2C
43 select SND_SOC_TPA6130A2 if I2C 48 select SND_SOC_TPA6130A2 if I2C
44 select SND_SOC_TLV320DAC33 if I2C 49 select SND_SOC_TLV320DAC33 if I2C
@@ -173,15 +178,25 @@ config SND_SOC_L3
173config SND_SOC_DA7210 178config SND_SOC_DA7210
174 tristate 179 tristate
175 180
181config SND_SOC_DFBMCS320
182 tristate
183
176config SND_SOC_DMIC 184config SND_SOC_DMIC
177 tristate 185 tristate
178 186
179config SND_SOC_MAX98088 187config SND_SOC_MAX98088
180 tristate 188 tristate
181 189
190config SND_SOC_MAX9850
191 tristate
192
182config SND_SOC_PCM3008 193config SND_SOC_PCM3008
183 tristate 194 tristate
184 195
196#Freescale sgtl5000 codec
197config SND_SOC_SGTL5000
198 tristate
199
185config SND_SOC_SN95031 200config SND_SOC_SN95031
186 tristate 201 tristate
187 202
@@ -201,6 +216,9 @@ config SND_SOC_TLV320AIC26
201 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 216 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
202 depends on SPI 217 depends on SPI
203 218
219config SND_SOC_TVL320AIC32X4
220 tristate
221
204config SND_SOC_TLV320AIC3X 222config SND_SOC_TLV320AIC3X
205 tristate 223 tristate
206 224
@@ -338,6 +356,9 @@ config SND_SOC_WM9713
338 tristate 356 tristate
339 357
340# Amp 358# Amp
359config SND_SOC_LM4857
360 tristate
361
341config SND_SOC_MAX9877 362config SND_SOC_MAX9877
342 tristate 363 tristate
343 364
@@ -349,4 +370,3 @@ config SND_SOC_WM2000
349 370
350config SND_SOC_WM9090 371config SND_SOC_WM9090
351 tristate 372 tristate
352
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 83b7accd7037..379bc55f0723 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -15,10 +15,13 @@ snd-soc-cs4270-objs := cs4270.o
15snd-soc-cs4271-objs := cs4271.o 15snd-soc-cs4271-objs := cs4271.o
16snd-soc-cx20442-objs := cx20442.o 16snd-soc-cx20442-objs := cx20442.o
17snd-soc-da7210-objs := da7210.o 17snd-soc-da7210-objs := da7210.o
18snd-soc-dfbmcs320-objs := dfbmcs320.o
18snd-soc-dmic-objs := dmic.o 19snd-soc-dmic-objs := dmic.o
19snd-soc-l3-objs := l3.o 20snd-soc-l3-objs := l3.o
20snd-soc-max98088-objs := max98088.o 21snd-soc-max98088-objs := max98088.o
22snd-soc-max9850-objs := max9850.o
21snd-soc-pcm3008-objs := pcm3008.o 23snd-soc-pcm3008-objs := pcm3008.o
24snd-soc-sgtl5000-objs := sgtl5000.o
22snd-soc-alc5623-objs := alc5623.o 25snd-soc-alc5623-objs := alc5623.o
23snd-soc-sn95031-objs := sn95031.o 26snd-soc-sn95031-objs := sn95031.o
24snd-soc-spdif-objs := spdif_transciever.o 27snd-soc-spdif-objs := spdif_transciever.o
@@ -27,6 +30,7 @@ snd-soc-stac9766-objs := stac9766.o
27snd-soc-tlv320aic23-objs := tlv320aic23.o 30snd-soc-tlv320aic23-objs := tlv320aic23.o
28snd-soc-tlv320aic26-objs := tlv320aic26.o 31snd-soc-tlv320aic26-objs := tlv320aic26.o
29snd-soc-tlv320aic3x-objs := tlv320aic3x.o 32snd-soc-tlv320aic3x-objs := tlv320aic3x.o
33snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
30snd-soc-tlv320dac33-objs := tlv320dac33.o 34snd-soc-tlv320dac33-objs := tlv320dac33.o
31snd-soc-twl4030-objs := twl4030.o 35snd-soc-twl4030-objs := twl4030.o
32snd-soc-twl6040-objs := twl6040.o 36snd-soc-twl6040-objs := twl6040.o
@@ -75,6 +79,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
75snd-soc-jz4740-codec-objs := jz4740.o 79snd-soc-jz4740-codec-objs := jz4740.o
76 80
77# Amp 81# Amp
82snd-soc-lm4857-objs := lm4857.o
78snd-soc-max9877-objs := max9877.o 83snd-soc-max9877-objs := max9877.o
79snd-soc-tpa6130a2-objs := tpa6130a2.o 84snd-soc-tpa6130a2-objs := tpa6130a2.o
80snd-soc-wm2000-objs := wm2000.o 85snd-soc-wm2000-objs := wm2000.o
@@ -91,18 +96,21 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
91obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 96obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
92obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 97obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
93obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 98obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
99obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
94obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 100obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
95obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 101obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
96obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 102obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
97obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 103obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
98obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 104obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
99obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 105obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
106obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
100obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 107obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
101obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 108obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
102obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 109obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
103obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 110obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
111obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
104obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 112obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
105obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 113obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
106obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 114obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
107obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 115obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
108obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 116obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
@@ -110,6 +118,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
110obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 118obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
111obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 119obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
112obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 120obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
121obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o
113obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 122obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
114obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 123obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
115obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 124obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
@@ -157,6 +166,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
157obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o 166obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
158 167
159# Amp 168# Amp
169obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
160obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 170obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
161obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 171obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
162obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 172obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index c27f8f59dc66..cbf0b6d400b8 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -294,7 +294,6 @@ static struct spi_driver ak4104_spi_driver = {
294 294
295static int __init ak4104_init(void) 295static int __init ak4104_init(void)
296{ 296{
297 pr_info("Asahi Kasei AK4104 ALSA SoC Codec Driver\n");
298 return spi_register_driver(&ak4104_spi_driver); 297 return spi_register_driver(&ak4104_spi_driver);
299} 298}
300module_init(ak4104_init); 299module_init(ak4104_init);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index c0fccadaea9a..0206a17d7283 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -719,7 +719,7 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client)
719/* 719/*
720 * cs4270_id - I2C device IDs supported by this driver 720 * cs4270_id - I2C device IDs supported by this driver
721 */ 721 */
722static struct i2c_device_id cs4270_id[] = { 722static const struct i2c_device_id cs4270_id[] = {
723 {"cs4270", 0}, 723 {"cs4270", 0},
724 {} 724 {}
725}; 725};
@@ -743,8 +743,6 @@ static struct i2c_driver cs4270_i2c_driver = {
743 743
744static int __init cs4270_init(void) 744static int __init cs4270_init(void)
745{ 745{
746 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
747
748 return i2c_add_driver(&cs4270_i2c_driver); 746 return i2c_add_driver(&cs4270_i2c_driver);
749} 747}
750module_init(cs4270_init); 748module_init(cs4270_init);
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 9c5b7db0ce6a..083aab96ca80 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -33,6 +33,7 @@
33#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 33#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S24_LE | \ 34 SNDRV_PCM_FMTBIT_S24_LE | \
35 SNDRV_PCM_FMTBIT_S32_LE) 35 SNDRV_PCM_FMTBIT_S32_LE)
36#define CS4271_PCM_RATES SNDRV_PCM_RATE_8000_192000
36 37
37/* 38/*
38 * CS4271 registers 39 * CS4271 registers
@@ -167,27 +168,6 @@ struct cs4271_private {
167 int gpio_disable; 168 int gpio_disable;
168}; 169};
169 170
170struct cs4271_clk_cfg {
171 unsigned int ratio; /* MCLK / sample rate */
172 u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
173 u8 mclk_master; /* ratio bit mask for Master mode */
174 u8 mclk_slave; /* ratio bit mask for Slave mode */
175};
176
177static struct cs4271_clk_cfg cs4271_clk_tab[] = {
178 {64, CS4271_MODE1_MODE_4X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1},
179 {96, CS4271_MODE1_MODE_4X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1},
180 {128, CS4271_MODE1_MODE_2X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1},
181 {192, CS4271_MODE1_MODE_2X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1},
182 {256, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_1, CS4271_MODE1_DIV_1},
183 {384, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_15, CS4271_MODE1_DIV_1},
184 {512, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_2, CS4271_MODE1_DIV_1},
185 {768, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_3, CS4271_MODE1_DIV_3},
186 {1024, CS4271_MODE1_MODE_1X, CS4271_MODE1_DIV_3, CS4271_MODE1_DIV_3}
187};
188
189#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
190
191/* 171/*
192 * @freq is the desired MCLK rate 172 * @freq is the desired MCLK rate
193 * MCLK rate should (c) be the sample rate, multiplied by one of the 173 * MCLK rate should (c) be the sample rate, multiplied by one of the
@@ -296,6 +276,45 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
296 return cs4271_set_deemph(codec); 276 return cs4271_set_deemph(codec);
297} 277}
298 278
279struct cs4271_clk_cfg {
280 bool master; /* codec mode */
281 u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
282 unsigned short ratio; /* MCLK / sample rate */
283 u8 ratio_mask; /* ratio bit mask for Master mode */
284};
285
286static struct cs4271_clk_cfg cs4271_clk_tab[] = {
287 {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
288 {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15},
289 {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2},
290 {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3},
291 {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
292 {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15},
293 {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2},
294 {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3},
295 {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
296 {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15},
297 {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2},
298 {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3},
299 {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
300 {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1},
301 {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1},
302 {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2},
303 {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2},
304 {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
305 {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1},
306 {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1},
307 {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2},
308 {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2},
309 {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
310 {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1},
311 {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1},
312 {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2},
313 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
314};
315
316#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
317
299static int cs4271_hw_params(struct snd_pcm_substream *substream, 318static int cs4271_hw_params(struct snd_pcm_substream *substream,
300 struct snd_pcm_hw_params *params, 319 struct snd_pcm_hw_params *params,
301 struct snd_soc_dai *dai) 320 struct snd_soc_dai *dai)
@@ -307,23 +326,28 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
307 unsigned int ratio, val; 326 unsigned int ratio, val;
308 327
309 cs4271->rate = params_rate(params); 328 cs4271->rate = params_rate(params);
329
330 /* Configure DAC */
331 if (cs4271->rate < 50000)
332 val = CS4271_MODE1_MODE_1X;
333 else if (cs4271->rate < 100000)
334 val = CS4271_MODE1_MODE_2X;
335 else
336 val = CS4271_MODE1_MODE_4X;
337
310 ratio = cs4271->mclk / cs4271->rate; 338 ratio = cs4271->mclk / cs4271->rate;
311 for (i = 0; i < CS4171_NR_RATIOS; i++) 339 for (i = 0; i < CS4171_NR_RATIOS; i++)
312 if (cs4271_clk_tab[i].ratio == ratio) 340 if ((cs4271_clk_tab[i].master == cs4271->master) &&
341 (cs4271_clk_tab[i].speed_mode == val) &&
342 (cs4271_clk_tab[i].ratio == ratio))
313 break; 343 break;
314 344
315 if ((i == CS4171_NR_RATIOS) || ((ratio == 1024) && cs4271->master)) { 345 if (i == CS4171_NR_RATIOS) {
316 dev_err(codec->dev, "Invalid sample rate\n"); 346 dev_err(codec->dev, "Invalid sample rate\n");
317 return -EINVAL; 347 return -EINVAL;
318 } 348 }
319 349
320 /* Configure DAC */ 350 val |= cs4271_clk_tab[i].ratio_mask;
321 val = cs4271_clk_tab[i].speed_mode;
322
323 if (cs4271->master)
324 val |= cs4271_clk_tab[i].mclk_master;
325 else
326 val |= cs4271_clk_tab[i].mclk_slave;
327 351
328 ret = snd_soc_update_bits(codec, CS4271_MODE1, 352 ret = snd_soc_update_bits(codec, CS4271_MODE1,
329 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val); 353 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
@@ -392,14 +416,14 @@ static struct snd_soc_dai_driver cs4271_dai = {
392 .stream_name = "Playback", 416 .stream_name = "Playback",
393 .channels_min = 2, 417 .channels_min = 2,
394 .channels_max = 2, 418 .channels_max = 2,
395 .rates = SNDRV_PCM_RATE_8000_96000, 419 .rates = CS4271_PCM_RATES,
396 .formats = CS4271_PCM_FORMATS, 420 .formats = CS4271_PCM_FORMATS,
397 }, 421 },
398 .capture = { 422 .capture = {
399 .stream_name = "Capture", 423 .stream_name = "Capture",
400 .channels_min = 2, 424 .channels_min = 2,
401 .channels_max = 2, 425 .channels_max = 2,
402 .rates = SNDRV_PCM_RATE_8000_96000, 426 .rates = CS4271_PCM_RATES,
403 .formats = CS4271_PCM_FORMATS, 427 .formats = CS4271_PCM_FORMATS,
404 }, 428 },
405 .ops = &cs4271_dai_ops, 429 .ops = &cs4271_dai_ops,
@@ -441,22 +465,11 @@ static int cs4271_probe(struct snd_soc_codec *codec)
441 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; 465 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
442 int ret; 466 int ret;
443 int gpio_nreset = -EINVAL; 467 int gpio_nreset = -EINVAL;
444 int gpio_disable = -EINVAL;
445 468
446 codec->control_data = cs4271->control_data; 469 codec->control_data = cs4271->control_data;
447 470
448 if (cs4271plat) { 471 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
449 if (gpio_is_valid(cs4271plat->gpio_nreset)) 472 gpio_nreset = cs4271plat->gpio_nreset;
450 gpio_nreset = cs4271plat->gpio_nreset;
451 if (gpio_is_valid(cs4271plat->gpio_disable))
452 gpio_disable = cs4271plat->gpio_disable;
453 }
454
455 if (gpio_disable >= 0)
456 if (gpio_request(gpio_disable, "CS4271 Disable"))
457 gpio_disable = -EINVAL;
458 if (gpio_disable >= 0)
459 gpio_direction_output(gpio_disable, 0);
460 473
461 if (gpio_nreset >= 0) 474 if (gpio_nreset >= 0)
462 if (gpio_request(gpio_nreset, "CS4271 Reset")) 475 if (gpio_request(gpio_nreset, "CS4271 Reset"))
@@ -471,7 +484,6 @@ static int cs4271_probe(struct snd_soc_codec *codec)
471 } 484 }
472 485
473 cs4271->gpio_nreset = gpio_nreset; 486 cs4271->gpio_nreset = gpio_nreset;
474 cs4271->gpio_disable = gpio_disable;
475 487
476 /* 488 /*
477 * In case of I2C, chip address specified in board data. 489 * In case of I2C, chip address specified in board data.
@@ -509,10 +521,9 @@ static int cs4271_probe(struct snd_soc_codec *codec)
509static int cs4271_remove(struct snd_soc_codec *codec) 521static int cs4271_remove(struct snd_soc_codec *codec)
510{ 522{
511 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 523 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
512 int gpio_nreset, gpio_disable; 524 int gpio_nreset;
513 525
514 gpio_nreset = cs4271->gpio_nreset; 526 gpio_nreset = cs4271->gpio_nreset;
515 gpio_disable = cs4271->gpio_disable;
516 527
517 if (gpio_is_valid(gpio_nreset)) { 528 if (gpio_is_valid(gpio_nreset)) {
518 /* Set codec to the reset state */ 529 /* Set codec to the reset state */
@@ -520,9 +531,6 @@ static int cs4271_remove(struct snd_soc_codec *codec)
520 gpio_free(gpio_nreset); 531 gpio_free(gpio_nreset);
521 } 532 }
522 533
523 if (gpio_is_valid(gpio_disable))
524 gpio_free(gpio_disable);
525
526 return 0; 534 return 0;
527}; 535};
528 536
@@ -571,7 +579,7 @@ static struct spi_driver cs4271_spi_driver = {
571#endif /* defined(CONFIG_SPI_MASTER) */ 579#endif /* defined(CONFIG_SPI_MASTER) */
572 580
573#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
574static struct i2c_device_id cs4271_i2c_id[] = { 582static const struct i2c_device_id cs4271_i2c_id[] = {
575 {"cs4271", 0}, 583 {"cs4271", 0},
576 {} 584 {}
577}; 585};
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index bb4bf65b9e7e..0bb424af956f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -367,7 +367,7 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
367 return 0; 367 return 0;
368} 368}
369 369
370static const u8 cx20442_reg = CX20442_TELOUT | CX20442_MIC; 370static const u8 cx20442_reg;
371 371
372static struct snd_soc_codec_driver cx20442_codec_dev = { 372static struct snd_soc_codec_driver cx20442_codec_dev = {
373 .probe = cx20442_codec_probe, 373 .probe = cx20442_codec_probe,
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c
new file mode 100644
index 000000000000..704bbde65737
--- /dev/null
+++ b/sound/soc/codecs/dfbmcs320.c
@@ -0,0 +1,72 @@
1/*
2 * Driver for the DFBM-CS320 bluetooth module
3 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15
16#include <sound/soc.h>
17
18static struct snd_soc_dai_driver dfbmcs320_dai = {
19 .name = "dfbmcs320-pcm",
20 .playback = {
21 .channels_min = 1,
22 .channels_max = 1,
23 .rates = SNDRV_PCM_RATE_8000,
24 .formats = SNDRV_PCM_FMTBIT_S16_LE,
25 },
26 .capture = {
27 .channels_min = 1,
28 .channels_max = 1,
29 .rates = SNDRV_PCM_RATE_8000,
30 .formats = SNDRV_PCM_FMTBIT_S16_LE,
31 },
32};
33
34static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
35
36static int __devinit dfbmcs320_probe(struct platform_device *pdev)
37{
38 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
39 &dfbmcs320_dai, 1);
40}
41
42static int __devexit dfbmcs320_remove(struct platform_device *pdev)
43{
44 snd_soc_unregister_codec(&pdev->dev);
45
46 return 0;
47}
48
49static struct platform_driver dfmcs320_driver = {
50 .driver = {
51 .name = "dfbmcs320",
52 .owner = THIS_MODULE,
53 },
54 .probe = dfbmcs320_probe,
55 .remove = __devexit_p(dfbmcs320_remove),
56};
57
58static int __init dfbmcs320_init(void)
59{
60 return platform_driver_register(&dfmcs320_driver);
61}
62module_init(dfbmcs320_init);
63
64static void __exit dfbmcs320_exit(void)
65{
66 platform_driver_unregister(&dfmcs320_driver);
67}
68module_exit(dfbmcs320_exit);
69
70MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
71MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
72MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
new file mode 100644
index 000000000000..72de47e5d040
--- /dev/null
+++ b/sound/soc/codecs/lm4857.c
@@ -0,0 +1,276 @@
1/*
2 * LM4857 AMP driver
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20
21#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/tlv.h>
24
25struct lm4857 {
26 struct i2c_client *i2c;
27 uint8_t mode;
28};
29
30static const uint8_t lm4857_default_regs[] = {
31 0x00, 0x00, 0x00, 0x00,
32};
33
34/* The register offsets in the cache array */
35#define LM4857_MVOL 0
36#define LM4857_LVOL 1
37#define LM4857_RVOL 2
38#define LM4857_CTRL 3
39
40/* the shifts required to set these bits */
41#define LM4857_3D 5
42#define LM4857_WAKEUP 5
43#define LM4857_EPGAIN 4
44
45static int lm4857_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value)
47{
48 uint8_t data;
49 int ret;
50
51 ret = snd_soc_cache_write(codec, reg, value);
52 if (ret < 0)
53 return ret;
54
55 data = (reg << 6) | value;
56 ret = i2c_master_send(codec->control_data, &data, 1);
57 if (ret != 1) {
58 dev_err(codec->dev, "Failed to write register: %d\n", ret);
59 return ret;
60 }
61
62 return 0;
63}
64
65static unsigned int lm4857_read(struct snd_soc_codec *codec,
66 unsigned int reg)
67{
68 unsigned int val;
69 int ret;
70
71 ret = snd_soc_cache_read(codec, reg, &val);
72 if (ret)
73 return -1;
74
75 return val;
76}
77
78static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
79 struct snd_ctl_elem_value *ucontrol)
80{
81 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
82 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
83
84 ucontrol->value.integer.value[0] = lm4857->mode;
85
86 return 0;
87}
88
89static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
94 uint8_t value = ucontrol->value.integer.value[0];
95
96 lm4857->mode = value;
97
98 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
99 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, value + 6);
100
101 return 1;
102}
103
104static int lm4857_set_bias_level(struct snd_soc_codec *codec,
105 enum snd_soc_bias_level level)
106{
107 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
108
109 switch (level) {
110 case SND_SOC_BIAS_ON:
111 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, lm4857->mode + 6);
112 break;
113 case SND_SOC_BIAS_STANDBY:
114 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, 0);
115 break;
116 default:
117 break;
118 }
119
120 codec->dapm.bias_level = level;
121
122 return 0;
123}
124
125static const char *lm4857_mode[] = {
126 "Earpiece",
127 "Loudspeaker",
128 "Loudspeaker + Headphone",
129 "Headphone",
130};
131
132static const struct soc_enum lm4857_mode_enum =
133 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
134
135static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
136 SND_SOC_DAPM_INPUT("IN"),
137
138 SND_SOC_DAPM_OUTPUT("LS"),
139 SND_SOC_DAPM_OUTPUT("HP"),
140 SND_SOC_DAPM_OUTPUT("EP"),
141};
142
143static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
144static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
145
146static const struct snd_kcontrol_new lm4857_controls[] = {
147 SOC_SINGLE_TLV("Left Playback Volume", LM4857_LVOL, 0, 31, 0,
148 stereo_tlv),
149 SOC_SINGLE_TLV("Right Playback Volume", LM4857_RVOL, 0, 31, 0,
150 stereo_tlv),
151 SOC_SINGLE_TLV("Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
152 mono_tlv),
153 SOC_SINGLE("Spk 3D Playback Switch", LM4857_LVOL, LM4857_3D, 1, 0),
154 SOC_SINGLE("HP 3D Playback Switch", LM4857_RVOL, LM4857_3D, 1, 0),
155 SOC_SINGLE("Fast Wakeup Playback Switch", LM4857_CTRL,
156 LM4857_WAKEUP, 1, 0),
157 SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
158 LM4857_EPGAIN, 1, 0),
159
160 SOC_ENUM_EXT("Mode", lm4857_mode_enum,
161 lm4857_get_mode, lm4857_set_mode),
162};
163
164/* There is a demux inbetween the the input signal and the output signals.
165 * Currently there is no easy way to model it in ASoC and since it does not make
166 * much of a difference in practice simply connect the input direclty to the
167 * outputs. */
168static const struct snd_soc_dapm_route lm4857_routes[] = {
169 {"LS", NULL, "IN"},
170 {"HP", NULL, "IN"},
171 {"EP", NULL, "IN"},
172};
173
174static int lm4857_probe(struct snd_soc_codec *codec)
175{
176 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
177 struct snd_soc_dapm_context *dapm = &codec->dapm;
178 int ret;
179
180 codec->control_data = lm4857->i2c;
181
182 ret = snd_soc_add_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls));
184 if (ret)
185 return ret;
186
187 ret = snd_soc_dapm_new_controls(dapm, lm4857_dapm_widgets,
188 ARRAY_SIZE(lm4857_dapm_widgets));
189 if (ret)
190 return ret;
191
192 ret = snd_soc_dapm_add_routes(dapm, lm4857_routes,
193 ARRAY_SIZE(lm4857_routes));
194 if (ret)
195 return ret;
196
197 snd_soc_dapm_new_widgets(dapm);
198
199 return 0;
200}
201
202static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
203 .write = lm4857_write,
204 .read = lm4857_read,
205 .probe = lm4857_probe,
206 .reg_cache_size = ARRAY_SIZE(lm4857_default_regs),
207 .reg_word_size = sizeof(uint8_t),
208 .reg_cache_default = lm4857_default_regs,
209 .set_bias_level = lm4857_set_bias_level,
210};
211
212static int __devinit lm4857_i2c_probe(struct i2c_client *i2c,
213 const struct i2c_device_id *id)
214{
215 struct lm4857 *lm4857;
216 int ret;
217
218 lm4857 = kzalloc(sizeof(*lm4857), GFP_KERNEL);
219 if (!lm4857)
220 return -ENOMEM;
221
222 i2c_set_clientdata(i2c, lm4857);
223
224 lm4857->i2c = i2c;
225
226 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
227
228 if (ret) {
229 kfree(lm4857);
230 return ret;
231 }
232
233 return 0;
234}
235
236static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
237{
238 struct lm4857 *lm4857 = i2c_get_clientdata(i2c);
239
240 snd_soc_unregister_codec(&i2c->dev);
241 kfree(lm4857);
242
243 return 0;
244}
245
246static const struct i2c_device_id lm4857_i2c_id[] = {
247 { "lm4857", 0 },
248 { }
249};
250MODULE_DEVICE_TABLE(i2c, lm4857_i2c_id);
251
252static struct i2c_driver lm4857_i2c_driver = {
253 .driver = {
254 .name = "lm4857",
255 .owner = THIS_MODULE,
256 },
257 .probe = lm4857_i2c_probe,
258 .remove = __devexit_p(lm4857_i2c_remove),
259 .id_table = lm4857_i2c_id,
260};
261
262static int __init lm4857_init(void)
263{
264 return i2c_add_driver(&lm4857_i2c_driver);
265}
266module_init(lm4857_init);
267
268static void __exit lm4857_exit(void)
269{
270 i2c_del_driver(&lm4857_i2c_driver);
271}
272module_exit(lm4857_exit);
273
274MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
275MODULE_DESCRIPTION("LM4857 amplifier driver");
276MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
new file mode 100644
index 000000000000..208d2ee61855
--- /dev/null
+++ b/sound/soc/codecs/max9850.c
@@ -0,0 +1,389 @@
1/*
2 * max9850.c -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 *
6 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
7 *
8 * Initial development of this code was funded by
9 * MICRONIC Computer Systeme GmbH, http://www.mcsberlin.de/
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/tlv.h>
26
27#include "max9850.h"
28
29struct max9850_priv {
30 unsigned int sysclk;
31};
32
33/* max9850 register cache */
34static const u8 max9850_reg[MAX9850_CACHEREGNUM] = {
35 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
36};
37
38/* these registers are not used at the moment but provided for the sake of
39 * completeness */
40static int max9850_volatile_register(struct snd_soc_codec *codec,
41 unsigned int reg)
42{
43 switch (reg) {
44 case MAX9850_STATUSA:
45 case MAX9850_STATUSB:
46 return 1;
47 default:
48 return 0;
49 }
50}
51
52static const unsigned int max9850_tlv[] = {
53 TLV_DB_RANGE_HEAD(4),
54 0x18, 0x1f, TLV_DB_SCALE_ITEM(-7450, 400, 0),
55 0x20, 0x33, TLV_DB_SCALE_ITEM(-4150, 200, 0),
56 0x34, 0x37, TLV_DB_SCALE_ITEM(-150, 100, 0),
57 0x38, 0x3f, TLV_DB_SCALE_ITEM(250, 50, 0),
58};
59
60static const struct snd_kcontrol_new max9850_controls[] = {
61SOC_SINGLE_TLV("Headphone Volume", MAX9850_VOLUME, 0, 0x3f, 1, max9850_tlv),
62SOC_SINGLE("Headphone Switch", MAX9850_VOLUME, 7, 1, 1),
63SOC_SINGLE("Mono Switch", MAX9850_GENERAL_PURPOSE, 2, 1, 0),
64};
65
66static const struct snd_kcontrol_new max9850_mixer_controls[] = {
67 SOC_DAPM_SINGLE("Line In Switch", MAX9850_ENABLE, 1, 1, 0),
68};
69
70static const struct snd_soc_dapm_widget max9850_dapm_widgets[] = {
71SND_SOC_DAPM_SUPPLY("Charge Pump 1", MAX9850_ENABLE, 4, 0, NULL, 0),
72SND_SOC_DAPM_SUPPLY("Charge Pump 2", MAX9850_ENABLE, 5, 0, NULL, 0),
73SND_SOC_DAPM_SUPPLY("MCLK", MAX9850_ENABLE, 6, 0, NULL, 0),
74SND_SOC_DAPM_SUPPLY("SHDN", MAX9850_ENABLE, 7, 0, NULL, 0),
75SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", MAX9850_ENABLE, 2, 0,
76 &max9850_mixer_controls[0],
77 ARRAY_SIZE(max9850_mixer_controls)),
78SND_SOC_DAPM_PGA("Headphone Output", MAX9850_ENABLE, 3, 0, NULL, 0),
79SND_SOC_DAPM_DAC("DAC", "HiFi Playback", MAX9850_ENABLE, 0, 0),
80SND_SOC_DAPM_OUTPUT("OUTL"),
81SND_SOC_DAPM_OUTPUT("HPL"),
82SND_SOC_DAPM_OUTPUT("OUTR"),
83SND_SOC_DAPM_OUTPUT("HPR"),
84SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
85SND_SOC_DAPM_INPUT("INL"),
86SND_SOC_DAPM_INPUT("INR"),
87};
88
89static const struct snd_soc_dapm_route intercon[] = {
90 /* output mixer */
91 {"Output Mixer", NULL, "DAC"},
92 {"Output Mixer", "Line In Switch", "Line Input"},
93
94 /* outputs */
95 {"Headphone Output", NULL, "Output Mixer"},
96 {"HPL", NULL, "Headphone Output"},
97 {"HPR", NULL, "Headphone Output"},
98 {"OUTL", NULL, "Output Mixer"},
99 {"OUTR", NULL, "Output Mixer"},
100
101 /* inputs */
102 {"Line Input", NULL, "INL"},
103 {"Line Input", NULL, "INR"},
104
105 /* supplies */
106 {"Output Mixer", NULL, "Charge Pump 1"},
107 {"Output Mixer", NULL, "Charge Pump 2"},
108 {"Output Mixer", NULL, "SHDN"},
109 {"DAC", NULL, "MCLK"},
110};
111
112static int max9850_hw_params(struct snd_pcm_substream *substream,
113 struct snd_pcm_hw_params *params,
114 struct snd_soc_dai *dai)
115{
116 struct snd_soc_codec *codec = dai->codec;
117 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
118 u64 lrclk_div;
119 u8 sf, da;
120
121 if (!max9850->sysclk)
122 return -EINVAL;
123
124 /* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
125 sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
126 lrclk_div = (1 << 22);
127 lrclk_div *= params_rate(params);
128 lrclk_div *= sf;
129 do_div(lrclk_div, max9850->sysclk);
130
131 snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
132 snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
133
134 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE:
136 da = 0;
137 break;
138 case SNDRV_PCM_FORMAT_S20_3LE:
139 da = 0x2;
140 break;
141 case SNDRV_PCM_FORMAT_S24_LE:
142 da = 0x3;
143 break;
144 default:
145 return -EINVAL;
146 }
147 snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
148
149 return 0;
150}
151
152static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
153 int clk_id, unsigned int freq, int dir)
154{
155 struct snd_soc_codec *codec = codec_dai->codec;
156 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
157
158 /* calculate mclk -> iclk divider */
159 if (freq <= 13000000)
160 snd_soc_write(codec, MAX9850_CLOCK, 0x0);
161 else if (freq <= 26000000)
162 snd_soc_write(codec, MAX9850_CLOCK, 0x4);
163 else if (freq <= 40000000)
164 snd_soc_write(codec, MAX9850_CLOCK, 0x8);
165 else
166 return -EINVAL;
167
168 max9850->sysclk = freq;
169 return 0;
170}
171
172static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
173{
174 struct snd_soc_codec *codec = codec_dai->codec;
175 u8 da = 0;
176
177 /* set master/slave audio interface */
178 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
179 case SND_SOC_DAIFMT_CBM_CFM:
180 da |= MAX9850_MASTER;
181 break;
182 case SND_SOC_DAIFMT_CBS_CFS:
183 break;
184 default:
185 return -EINVAL;
186 }
187
188 /* interface format */
189 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
190 case SND_SOC_DAIFMT_I2S:
191 da |= MAX9850_DLY;
192 break;
193 case SND_SOC_DAIFMT_RIGHT_J:
194 da |= MAX9850_RTJ;
195 break;
196 case SND_SOC_DAIFMT_LEFT_J:
197 break;
198 default:
199 return -EINVAL;
200 }
201
202 /* clock inversion */
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 break;
206 case SND_SOC_DAIFMT_IB_IF:
207 da |= MAX9850_BCINV | MAX9850_INV;
208 break;
209 case SND_SOC_DAIFMT_IB_NF:
210 da |= MAX9850_BCINV;
211 break;
212 case SND_SOC_DAIFMT_NB_IF:
213 da |= MAX9850_INV;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 /* set da */
220 snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
221
222 return 0;
223}
224
225static int max9850_set_bias_level(struct snd_soc_codec *codec,
226 enum snd_soc_bias_level level)
227{
228 int ret;
229
230 switch (level) {
231 case SND_SOC_BIAS_ON:
232 break;
233 case SND_SOC_BIAS_PREPARE:
234 break;
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
237 ret = snd_soc_cache_sync(codec);
238 if (ret) {
239 dev_err(codec->dev,
240 "Failed to sync cache: %d\n", ret);
241 return ret;
242 }
243 }
244 break;
245 case SND_SOC_BIAS_OFF:
246 break;
247 }
248 codec->dapm.bias_level = level;
249 return 0;
250}
251
252#define MAX9850_RATES SNDRV_PCM_RATE_8000_48000
253
254#define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
255 SNDRV_PCM_FMTBIT_S24_LE)
256
257static struct snd_soc_dai_ops max9850_dai_ops = {
258 .hw_params = max9850_hw_params,
259 .set_sysclk = max9850_set_dai_sysclk,
260 .set_fmt = max9850_set_dai_fmt,
261};
262
263static struct snd_soc_dai_driver max9850_dai = {
264 .name = "max9850-hifi",
265 .playback = {
266 .stream_name = "Playback",
267 .channels_min = 1,
268 .channels_max = 2,
269 .rates = MAX9850_RATES,
270 .formats = MAX9850_FORMATS
271 },
272 .ops = &max9850_dai_ops,
273};
274
275#ifdef CONFIG_PM
276static int max9850_suspend(struct snd_soc_codec *codec, pm_message_t state)
277{
278 max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
279
280 return 0;
281}
282
283static int max9850_resume(struct snd_soc_codec *codec)
284{
285 max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
286
287 return 0;
288}
289#else
290#define max9850_suspend NULL
291#define max9850_resume NULL
292#endif
293
294static int max9850_probe(struct snd_soc_codec *codec)
295{
296 struct snd_soc_dapm_context *dapm = &codec->dapm;
297 int ret;
298
299 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
300 if (ret < 0) {
301 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
302 return ret;
303 }
304
305 /* enable zero-detect */
306 snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
307 /* enable slew-rate control */
308 snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
309 /* set slew-rate 125ms */
310 snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
311
312 snd_soc_dapm_new_controls(dapm, max9850_dapm_widgets,
313 ARRAY_SIZE(max9850_dapm_widgets));
314 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
315
316 snd_soc_add_controls(codec, max9850_controls,
317 ARRAY_SIZE(max9850_controls));
318
319 return 0;
320}
321
322static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
323 .probe = max9850_probe,
324 .suspend = max9850_suspend,
325 .resume = max9850_resume,
326 .set_bias_level = max9850_set_bias_level,
327 .reg_cache_size = ARRAY_SIZE(max9850_reg),
328 .reg_word_size = sizeof(u8),
329 .reg_cache_default = max9850_reg,
330 .volatile_register = max9850_volatile_register,
331};
332
333static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
334 const struct i2c_device_id *id)
335{
336 struct max9850_priv *max9850;
337 int ret;
338
339 max9850 = kzalloc(sizeof(struct max9850_priv), GFP_KERNEL);
340 if (max9850 == NULL)
341 return -ENOMEM;
342
343 i2c_set_clientdata(i2c, max9850);
344
345 ret = snd_soc_register_codec(&i2c->dev,
346 &soc_codec_dev_max9850, &max9850_dai, 1);
347 if (ret < 0)
348 kfree(max9850);
349 return ret;
350}
351
352static __devexit int max9850_i2c_remove(struct i2c_client *client)
353{
354 snd_soc_unregister_codec(&client->dev);
355 kfree(i2c_get_clientdata(client));
356 return 0;
357}
358
359static const struct i2c_device_id max9850_i2c_id[] = {
360 { "max9850", 0 },
361 { }
362};
363MODULE_DEVICE_TABLE(i2c, max9850_i2c_id);
364
365static struct i2c_driver max9850_i2c_driver = {
366 .driver = {
367 .name = "max9850",
368 .owner = THIS_MODULE,
369 },
370 .probe = max9850_i2c_probe,
371 .remove = __devexit_p(max9850_i2c_remove),
372 .id_table = max9850_i2c_id,
373};
374
375static int __init max9850_init(void)
376{
377 return i2c_add_driver(&max9850_i2c_driver);
378}
379module_init(max9850_init);
380
381static void __exit max9850_exit(void)
382{
383 i2c_del_driver(&max9850_i2c_driver);
384}
385module_exit(max9850_exit);
386
387MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
388MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
389MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9850.h b/sound/soc/codecs/max9850.h
new file mode 100644
index 000000000000..72b1ddb04b0d
--- /dev/null
+++ b/sound/soc/codecs/max9850.h
@@ -0,0 +1,38 @@
1/*
2 * max9850.h -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _MAX9850_H
15#define _MAX9850_H
16
17#define MAX9850_STATUSA 0x00
18#define MAX9850_STATUSB 0x01
19#define MAX9850_VOLUME 0x02
20#define MAX9850_GENERAL_PURPOSE 0x03
21#define MAX9850_INTERRUPT 0x04
22#define MAX9850_ENABLE 0x05
23#define MAX9850_CLOCK 0x06
24#define MAX9850_CHARGE_PUMP 0x07
25#define MAX9850_LRCLK_MSB 0x08
26#define MAX9850_LRCLK_LSB 0x09
27#define MAX9850_DIGITAL_AUDIO 0x0a
28
29#define MAX9850_CACHEREGNUM 11
30
31/* MAX9850_DIGITAL_AUDIO */
32#define MAX9850_MASTER (1<<7)
33#define MAX9850_INV (1<<6)
34#define MAX9850_BCINV (1<<5)
35#define MAX9850_DLY (1<<3)
36#define MAX9850_RTJ (1<<2)
37
38#endif
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
new file mode 100644
index 000000000000..1f7217f703ee
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.c
@@ -0,0 +1,1513 @@
1/*
2 * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/clk.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h>
23#include <sound/core.h>
24#include <sound/tlv.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30
31#include "sgtl5000.h"
32
33#define SGTL5000_DAP_REG_OFFSET 0x0100
34#define SGTL5000_MAX_REG_OFFSET 0x013A
35
36/* default value of sgtl5000 registers except DAP */
37static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = {
38 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */
39 0x0000, /* 0x0002, CHIP_DIG_POWER. */
40 0x0008, /* 0x0004, CHIP_CKL_CTRL */
41 0x0010, /* 0x0006, CHIP_I2S_CTRL */
42 0x0000, /* 0x0008, reserved */
43 0x0008, /* 0x000A, CHIP_SSS_CTRL */
44 0x0000, /* 0x000C, reserved */
45 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */
46 0x3c3c, /* 0x0010, CHIP_DAC_VOL */
47 0x0000, /* 0x0012, reserved */
48 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */
49 0x0000, /* 0x0016, reserved */
50 0x0000, /* 0x0018, reserved */
51 0x0000, /* 0x001A, reserved */
52 0x0000, /* 0x001E, reserved */
53 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */
54 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */
55 0x0111, /* 0x0024, CHIP_ANN_CTRL */
56 0x0000, /* 0x0026, CHIP_LINREG_CTRL */
57 0x0000, /* 0x0028, CHIP_REF_CTRL */
58 0x0000, /* 0x002A, CHIP_MIC_CTRL */
59 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */
60 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */
61 0x7060, /* 0x0030, CHIP_ANA_POWER */
62 0x5000, /* 0x0032, CHIP_PLL_CTRL */
63 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */
64 0x0000, /* 0x0036, CHIP_ANA_STATUS */
65 0x0000, /* 0x0038, reserved */
66 0x0000, /* 0x003A, CHIP_ANA_TEST2 */
67 0x0000, /* 0x003C, CHIP_SHORT_CTRL */
68 0x0000, /* reserved */
69};
70
71/* default value of dap registers */
72static const u16 sgtl5000_dap_regs[] = {
73 0x0000, /* 0x0100, DAP_CONTROL */
74 0x0000, /* 0x0102, DAP_PEQ */
75 0x0040, /* 0x0104, DAP_BASS_ENHANCE */
76 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */
77 0x0000, /* 0x0108, DAP_AUDIO_EQ */
78 0x0040, /* 0x010A, DAP_SGTL_SURROUND */
79 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */
80 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */
81 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */
82 0x0000, /* 0x0112, reserved */
83 0x0000, /* 0x0114, reserved */
84 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */
85 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */
86 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */
87 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */
88 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */
89 0x8000, /* 0x0120, DAP_MAIN_CHAN */
90 0x0000, /* 0x0122, DAP_MIX_CHAN */
91 0x0510, /* 0x0124, DAP_AVC_CTRL */
92 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */
93 0x0028, /* 0x0128, DAP_AVC_ATTACK */
94 0x0050, /* 0x012A, DAP_AVC_DECAY */
95 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */
96 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */
97 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */
98 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */
99 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */
100 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */
101 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */
102 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */
103};
104
105/* regulator supplies for sgtl5000, VDDD is an optional external supply */
106enum sgtl5000_regulator_supplies {
107 VDDA,
108 VDDIO,
109 VDDD,
110 SGTL5000_SUPPLY_NUM
111};
112
113/* vddd is optional supply */
114static const char *supply_names[SGTL5000_SUPPLY_NUM] = {
115 "VDDA",
116 "VDDIO",
117 "VDDD"
118};
119
120#define LDO_CONSUMER_NAME "VDDD_LDO"
121#define LDO_VOLTAGE 1200000
122
123static struct regulator_consumer_supply ldo_consumer[] = {
124 REGULATOR_SUPPLY(LDO_CONSUMER_NAME, NULL),
125};
126
127static struct regulator_init_data ldo_init_data = {
128 .constraints = {
129 .min_uV = 850000,
130 .max_uV = 1600000,
131 .valid_modes_mask = REGULATOR_MODE_NORMAL,
132 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
133 },
134 .num_consumer_supplies = 1,
135 .consumer_supplies = &ldo_consumer[0],
136};
137
138/*
139 * sgtl5000 internal ldo regulator,
140 * enabled when VDDD not provided
141 */
142struct ldo_regulator {
143 struct regulator_desc desc;
144 struct regulator_dev *dev;
145 int voltage;
146 void *codec_data;
147 bool enabled;
148};
149
150/* sgtl5000 private structure in codec */
151struct sgtl5000_priv {
152 int sysclk; /* sysclk rate */
153 int master; /* i2s master or not */
154 int fmt; /* i2s data format */
155 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
156 struct ldo_regulator *ldo;
157};
158
159/*
160 * mic_bias power on/off share the same register bits with
161 * output impedance of mic bias, when power on mic bias, we
162 * need reclaim it to impedance value.
163 * 0x0 = Powered off
164 * 0x1 = 2Kohm
165 * 0x2 = 4Kohm
166 * 0x3 = 8Kohm
167 */
168static int mic_bias_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *kcontrol, int event)
170{
171 switch (event) {
172 case SND_SOC_DAPM_POST_PMU:
173 /* change mic bias resistor to 4Kohm */
174 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
175 SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k);
176 break;
177
178 case SND_SOC_DAPM_PRE_PMD:
179 /*
180 * SGTL5000_BIAS_R_8k as mask to clean the two bits
181 * of mic bias and output impedance
182 */
183 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
184 SGTL5000_BIAS_R_8k, 0);
185 break;
186 }
187 return 0;
188}
189
190/*
191 * using codec assist to small pop, hp_powerup or lineout_powerup
192 * should stay setting until vag_powerup is fully ramped down,
193 * vag fully ramped down require 400ms.
194 */
195static int small_pop_event(struct snd_soc_dapm_widget *w,
196 struct snd_kcontrol *kcontrol, int event)
197{
198 switch (event) {
199 case SND_SOC_DAPM_PRE_PMU:
200 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
201 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
202 break;
203
204 case SND_SOC_DAPM_PRE_PMD:
205 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
206 SGTL5000_VAG_POWERUP, 0);
207 msleep(400);
208 break;
209 default:
210 break;
211 }
212
213 return 0;
214}
215
216/* input sources for ADC */
217static const char *adc_mux_text[] = {
218 "MIC_IN", "LINE_IN"
219};
220
221static const struct soc_enum adc_enum =
222SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text);
223
224static const struct snd_kcontrol_new adc_mux =
225SOC_DAPM_ENUM("Capture Mux", adc_enum);
226
227/* input sources for DAC */
228static const char *dac_mux_text[] = {
229 "DAC", "LINE_IN"
230};
231
232static const struct soc_enum dac_enum =
233SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text);
234
235static const struct snd_kcontrol_new dac_mux =
236SOC_DAPM_ENUM("Headphone Mux", dac_enum);
237
238static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
239 SND_SOC_DAPM_INPUT("LINE_IN"),
240 SND_SOC_DAPM_INPUT("MIC_IN"),
241
242 SND_SOC_DAPM_OUTPUT("HP_OUT"),
243 SND_SOC_DAPM_OUTPUT("LINE_OUT"),
244
245 SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
246 mic_bias_event,
247 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
248
249 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
250 small_pop_event,
251 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
252 SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0,
253 small_pop_event,
254 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
255
256 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
257 SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
258
259 /* aif for i2s input */
260 SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
261 0, SGTL5000_CHIP_DIG_POWER,
262 0, 0),
263
264 /* aif for i2s output */
265 SND_SOC_DAPM_AIF_OUT("AIFOUT", "Capture",
266 0, SGTL5000_CHIP_DIG_POWER,
267 1, 0),
268
269 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
270
271 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
272};
273
274/* routes for sgtl5000 */
275static const struct snd_soc_dapm_route audio_map[] = {
276 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
277 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
278
279 {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */
280 {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */
281
282 {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */
283 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
284 {"LO", NULL, "DAC"}, /* dac --> line_out */
285
286 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
287 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
288
289 {"LINE_OUT", NULL, "LO"},
290 {"HP_OUT", NULL, "HP"},
291};
292
293/* custom function to fetch info of PCM playback volume */
294static int dac_info_volsw(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_info *uinfo)
296{
297 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
298 uinfo->count = 2;
299 uinfo->value.integer.min = 0;
300 uinfo->value.integer.max = 0xfc - 0x3c;
301 return 0;
302}
303
304/*
305 * custom function to get of PCM playback volume
306 *
307 * dac volume register
308 * 15-------------8-7--------------0
309 * | R channel vol | L channel vol |
310 * -------------------------------
311 *
312 * PCM volume with 0.5017 dB steps from 0 to -90 dB
313 *
314 * register values map to dB
315 * 0x3B and less = Reserved
316 * 0x3C = 0 dB
317 * 0x3D = -0.5 dB
318 * 0xF0 = -90 dB
319 * 0xFC and greater = Muted
320 *
321 * register value map to userspace value
322 *
323 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
324 * ------------------------------
325 * userspace value 0xc0 0
326 */
327static int dac_get_volsw(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol)
329{
330 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
331 int reg;
332 int l;
333 int r;
334
335 reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
336
337 /* get left channel volume */
338 l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
339
340 /* get right channel volume */
341 r = (reg & SGTL5000_DAC_VOL_RIGHT_MASK) >> SGTL5000_DAC_VOL_RIGHT_SHIFT;
342
343 /* make sure value fall in (0x3c,0xfc) */
344 l = clamp(l, 0x3c, 0xfc);
345 r = clamp(r, 0x3c, 0xfc);
346
347 /* invert it and map to userspace value */
348 l = 0xfc - l;
349 r = 0xfc - r;
350
351 ucontrol->value.integer.value[0] = l;
352 ucontrol->value.integer.value[1] = r;
353
354 return 0;
355}
356
357/*
358 * custom function to put of PCM playback volume
359 *
360 * dac volume register
361 * 15-------------8-7--------------0
362 * | R channel vol | L channel vol |
363 * -------------------------------
364 *
365 * PCM volume with 0.5017 dB steps from 0 to -90 dB
366 *
367 * register values map to dB
368 * 0x3B and less = Reserved
369 * 0x3C = 0 dB
370 * 0x3D = -0.5 dB
371 * 0xF0 = -90 dB
372 * 0xFC and greater = Muted
373 *
374 * userspace value map to register value
375 *
376 * userspace value 0xc0 0
377 * ------------------------------
378 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
379 */
380static int dac_put_volsw(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 int reg;
385 int l;
386 int r;
387
388 l = ucontrol->value.integer.value[0];
389 r = ucontrol->value.integer.value[1];
390
391 /* make sure userspace volume fall in (0, 0xfc-0x3c) */
392 l = clamp(l, 0, 0xfc - 0x3c);
393 r = clamp(r, 0, 0xfc - 0x3c);
394
395 /* invert it, get the value can be set to register */
396 l = 0xfc - l;
397 r = 0xfc - r;
398
399 /* shift to get the register value */
400 reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
401 r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
402
403 snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
404
405 return 0;
406}
407
408static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
409
410/* tlv for mic gain, 0db 20db 30db 40db */
411static const unsigned int mic_gain_tlv[] = {
412 TLV_DB_RANGE_HEAD(4),
413 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
414 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
415};
416
417/* tlv for hp volume, -51.5db to 12.0db, step .5db */
418static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
419
420static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
421 /* SOC_DOUBLE_S8_TLV with invert */
422 {
423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
424 .name = "PCM Playback Volume",
425 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
426 SNDRV_CTL_ELEM_ACCESS_READWRITE,
427 .info = dac_info_volsw,
428 .get = dac_get_volsw,
429 .put = dac_put_volsw,
430 },
431
432 SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0),
433 SOC_SINGLE_TLV("Capture Attenuate Switch (-6dB)",
434 SGTL5000_CHIP_ANA_ADC_CTRL,
435 8, 2, 0, capture_6db_attenuate),
436 SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
437
438 SOC_DOUBLE_TLV("Headphone Playback Volume",
439 SGTL5000_CHIP_ANA_HP_CTRL,
440 0, 8,
441 0x7f, 1,
442 headphone_volume),
443 SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
444 5, 1, 0),
445
446 SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL,
447 0, 4, 0, mic_gain_tlv),
448};
449
450/* mute the codec used by alsa core */
451static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
452{
453 struct snd_soc_codec *codec = codec_dai->codec;
454 u16 adcdac_ctrl = SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT;
455
456 snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
457 adcdac_ctrl, mute ? adcdac_ctrl : 0);
458
459 return 0;
460}
461
462/* set codec format */
463static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
464{
465 struct snd_soc_codec *codec = codec_dai->codec;
466 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
467 u16 i2sctl = 0;
468
469 sgtl5000->master = 0;
470 /*
471 * i2s clock and frame master setting.
472 * ONLY support:
473 * - clock and frame slave,
474 * - clock and frame master
475 */
476 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
477 case SND_SOC_DAIFMT_CBS_CFS:
478 break;
479 case SND_SOC_DAIFMT_CBM_CFM:
480 i2sctl |= SGTL5000_I2S_MASTER;
481 sgtl5000->master = 1;
482 break;
483 default:
484 return -EINVAL;
485 }
486
487 /* setting i2s data format */
488 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
489 case SND_SOC_DAIFMT_DSP_A:
490 i2sctl |= SGTL5000_I2S_MODE_PCM;
491 break;
492 case SND_SOC_DAIFMT_DSP_B:
493 i2sctl |= SGTL5000_I2S_MODE_PCM;
494 i2sctl |= SGTL5000_I2S_LRALIGN;
495 break;
496 case SND_SOC_DAIFMT_I2S:
497 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
498 break;
499 case SND_SOC_DAIFMT_RIGHT_J:
500 i2sctl |= SGTL5000_I2S_MODE_RJ;
501 i2sctl |= SGTL5000_I2S_LRPOL;
502 break;
503 case SND_SOC_DAIFMT_LEFT_J:
504 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
505 i2sctl |= SGTL5000_I2S_LRALIGN;
506 break;
507 default:
508 return -EINVAL;
509 }
510
511 sgtl5000->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
512
513 /* Clock inversion */
514 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
515 case SND_SOC_DAIFMT_NB_NF:
516 break;
517 case SND_SOC_DAIFMT_IB_NF:
518 i2sctl |= SGTL5000_I2S_SCLK_INV;
519 break;
520 default:
521 return -EINVAL;
522 }
523
524 snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
525
526 return 0;
527}
528
529/* set codec sysclk */
530static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
531 int clk_id, unsigned int freq, int dir)
532{
533 struct snd_soc_codec *codec = codec_dai->codec;
534 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
535
536 switch (clk_id) {
537 case SGTL5000_SYSCLK:
538 sgtl5000->sysclk = freq;
539 break;
540 default:
541 return -EINVAL;
542 }
543
544 return 0;
545}
546
547/*
548 * set clock according to i2s frame clock,
549 * sgtl5000 provide 2 clock sources.
550 * 1. sys_mclk. sample freq can only configure to
551 * 1/256, 1/384, 1/512 of sys_mclk.
552 * 2. pll. can derive any audio clocks.
553 *
554 * clock setting rules:
555 * 1. in slave mode, only sys_mclk can use.
556 * 2. as constraint by sys_mclk, sample freq should
557 * set to 32k, 44.1k and above.
558 * 3. using sys_mclk prefer to pll to save power.
559 */
560static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
561{
562 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
563 int clk_ctl = 0;
564 int sys_fs; /* sample freq */
565
566 /*
567 * sample freq should be divided by frame clock,
568 * if frame clock lower than 44.1khz, sample feq should set to
569 * 32khz or 44.1khz.
570 */
571 switch (frame_rate) {
572 case 8000:
573 case 16000:
574 sys_fs = 32000;
575 break;
576 case 11025:
577 case 22050:
578 sys_fs = 44100;
579 break;
580 default:
581 sys_fs = frame_rate;
582 break;
583 }
584
585 /* set divided factor of frame clock */
586 switch (sys_fs / frame_rate) {
587 case 4:
588 clk_ctl |= SGTL5000_RATE_MODE_DIV_4 << SGTL5000_RATE_MODE_SHIFT;
589 break;
590 case 2:
591 clk_ctl |= SGTL5000_RATE_MODE_DIV_2 << SGTL5000_RATE_MODE_SHIFT;
592 break;
593 case 1:
594 clk_ctl |= SGTL5000_RATE_MODE_DIV_1 << SGTL5000_RATE_MODE_SHIFT;
595 break;
596 default:
597 return -EINVAL;
598 }
599
600 /* set the sys_fs according to frame rate */
601 switch (sys_fs) {
602 case 32000:
603 clk_ctl |= SGTL5000_SYS_FS_32k << SGTL5000_SYS_FS_SHIFT;
604 break;
605 case 44100:
606 clk_ctl |= SGTL5000_SYS_FS_44_1k << SGTL5000_SYS_FS_SHIFT;
607 break;
608 case 48000:
609 clk_ctl |= SGTL5000_SYS_FS_48k << SGTL5000_SYS_FS_SHIFT;
610 break;
611 case 96000:
612 clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
613 break;
614 default:
615 dev_err(codec->dev, "frame rate %d not supported\n",
616 frame_rate);
617 return -EINVAL;
618 }
619
620 /*
621 * calculate the divider of mclk/sample_freq,
622 * factor of freq =96k can only be 256, since mclk in range (12m,27m)
623 */
624 switch (sgtl5000->sysclk / sys_fs) {
625 case 256:
626 clk_ctl |= SGTL5000_MCLK_FREQ_256FS <<
627 SGTL5000_MCLK_FREQ_SHIFT;
628 break;
629 case 384:
630 clk_ctl |= SGTL5000_MCLK_FREQ_384FS <<
631 SGTL5000_MCLK_FREQ_SHIFT;
632 break;
633 case 512:
634 clk_ctl |= SGTL5000_MCLK_FREQ_512FS <<
635 SGTL5000_MCLK_FREQ_SHIFT;
636 break;
637 default:
638 /* if mclk not satisify the divider, use pll */
639 if (sgtl5000->master) {
640 clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
641 SGTL5000_MCLK_FREQ_SHIFT;
642 } else {
643 dev_err(codec->dev,
644 "PLL not supported in slave mode\n");
645 return -EINVAL;
646 }
647 }
648
649 /* if using pll, please check manual 6.4.2 for detail */
650 if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
651 u64 out, t;
652 int div2;
653 int pll_ctl;
654 unsigned int in, int_div, frac_div;
655
656 if (sgtl5000->sysclk > 17000000) {
657 div2 = 1;
658 in = sgtl5000->sysclk / 2;
659 } else {
660 div2 = 0;
661 in = sgtl5000->sysclk;
662 }
663 if (sys_fs == 44100)
664 out = 180633600;
665 else
666 out = 196608000;
667 t = do_div(out, in);
668 int_div = out;
669 t *= 2048;
670 do_div(t, in);
671 frac_div = t;
672 pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
673 frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
674
675 snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
676 if (div2)
677 snd_soc_update_bits(codec,
678 SGTL5000_CHIP_CLK_TOP_CTRL,
679 SGTL5000_INPUT_FREQ_DIV2,
680 SGTL5000_INPUT_FREQ_DIV2);
681 else
682 snd_soc_update_bits(codec,
683 SGTL5000_CHIP_CLK_TOP_CTRL,
684 SGTL5000_INPUT_FREQ_DIV2,
685 0);
686
687 /* power up pll */
688 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
689 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
690 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
691 } else {
692 /* power down pll */
693 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
694 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
695 0);
696 }
697
698 /* if using pll, clk_ctrl must be set after pll power up */
699 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
700
701 return 0;
702}
703
704/*
705 * Set PCM DAI bit size and sample rate.
706 * input: params_rate, params_fmt
707 */
708static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
709 struct snd_pcm_hw_params *params,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_codec *codec = rtd->codec;
714 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
715 int channels = params_channels(params);
716 int i2s_ctl = 0;
717 int stereo;
718 int ret;
719
720 /* sysclk should already set */
721 if (!sgtl5000->sysclk) {
722 dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
723 return -EFAULT;
724 }
725
726 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
727 stereo = SGTL5000_DAC_STEREO;
728 else
729 stereo = SGTL5000_ADC_STEREO;
730
731 /* set mono to save power */
732 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
733 channels == 1 ? 0 : stereo);
734
735 /* set codec clock base on lrclk */
736 ret = sgtl5000_set_clock(codec, params_rate(params));
737 if (ret)
738 return ret;
739
740 /* set i2s data format */
741 switch (params_format(params)) {
742 case SNDRV_PCM_FORMAT_S16_LE:
743 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
744 return -EINVAL;
745 i2s_ctl |= SGTL5000_I2S_DLEN_16 << SGTL5000_I2S_DLEN_SHIFT;
746 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_32FS <<
747 SGTL5000_I2S_SCLKFREQ_SHIFT;
748 break;
749 case SNDRV_PCM_FORMAT_S20_3LE:
750 i2s_ctl |= SGTL5000_I2S_DLEN_20 << SGTL5000_I2S_DLEN_SHIFT;
751 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
752 SGTL5000_I2S_SCLKFREQ_SHIFT;
753 break;
754 case SNDRV_PCM_FORMAT_S24_LE:
755 i2s_ctl |= SGTL5000_I2S_DLEN_24 << SGTL5000_I2S_DLEN_SHIFT;
756 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
757 SGTL5000_I2S_SCLKFREQ_SHIFT;
758 break;
759 case SNDRV_PCM_FORMAT_S32_LE:
760 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
761 return -EINVAL;
762 i2s_ctl |= SGTL5000_I2S_DLEN_32 << SGTL5000_I2S_DLEN_SHIFT;
763 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
764 SGTL5000_I2S_SCLKFREQ_SHIFT;
765 break;
766 default:
767 return -EINVAL;
768 }
769
770 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl);
771
772 return 0;
773}
774
775static int ldo_regulator_is_enabled(struct regulator_dev *dev)
776{
777 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
778
779 return ldo->enabled;
780}
781
782static int ldo_regulator_enable(struct regulator_dev *dev)
783{
784 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
785 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
786 int reg;
787
788 if (ldo_regulator_is_enabled(dev))
789 return 0;
790
791 /* set regulator value firstly */
792 reg = (1600 - ldo->voltage / 1000) / 50;
793 reg = clamp(reg, 0x0, 0xf);
794
795 /* amend the voltage value, unit: uV */
796 ldo->voltage = (1600 - reg * 50) * 1000;
797
798 /* set voltage to register */
799 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
800 (0x1 << 4) - 1, reg);
801
802 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
803 SGTL5000_LINEREG_D_POWERUP,
804 SGTL5000_LINEREG_D_POWERUP);
805
806 /* when internal ldo enabled, simple digital power can be disabled */
807 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
808 SGTL5000_LINREG_SIMPLE_POWERUP,
809 0);
810
811 ldo->enabled = 1;
812 return 0;
813}
814
815static int ldo_regulator_disable(struct regulator_dev *dev)
816{
817 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
818 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
819
820 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
821 SGTL5000_LINEREG_D_POWERUP,
822 0);
823
824 /* clear voltage info */
825 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
826 (0x1 << 4) - 1, 0);
827
828 ldo->enabled = 0;
829
830 return 0;
831}
832
833static int ldo_regulator_get_voltage(struct regulator_dev *dev)
834{
835 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
836
837 return ldo->voltage;
838}
839
840static struct regulator_ops ldo_regulator_ops = {
841 .is_enabled = ldo_regulator_is_enabled,
842 .enable = ldo_regulator_enable,
843 .disable = ldo_regulator_disable,
844 .get_voltage = ldo_regulator_get_voltage,
845};
846
847static int ldo_regulator_register(struct snd_soc_codec *codec,
848 struct regulator_init_data *init_data,
849 int voltage)
850{
851 struct ldo_regulator *ldo;
852
853 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
854
855 if (!ldo) {
856 dev_err(codec->dev, "failed to allocate ldo_regulator\n");
857 return -ENOMEM;
858 }
859
860 ldo->desc.name = kstrdup(dev_name(codec->dev), GFP_KERNEL);
861 if (!ldo->desc.name) {
862 kfree(ldo);
863 dev_err(codec->dev, "failed to allocate decs name memory\n");
864 return -ENOMEM;
865 }
866
867 ldo->desc.type = REGULATOR_VOLTAGE;
868 ldo->desc.owner = THIS_MODULE;
869 ldo->desc.ops = &ldo_regulator_ops;
870 ldo->desc.n_voltages = 1;
871
872 ldo->codec_data = codec;
873 ldo->voltage = voltage;
874
875 ldo->dev = regulator_register(&ldo->desc, codec->dev,
876 init_data, ldo);
877 if (IS_ERR(ldo->dev)) {
878 int ret = PTR_ERR(ldo->dev);
879
880 dev_err(codec->dev, "failed to register regulator\n");
881 kfree(ldo->desc.name);
882 kfree(ldo);
883
884 return ret;
885 }
886
887 return 0;
888}
889
890static int ldo_regulator_remove(struct snd_soc_codec *codec)
891{
892 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
893 struct ldo_regulator *ldo = sgtl5000->ldo;
894
895 if (!ldo)
896 return 0;
897
898 regulator_unregister(ldo->dev);
899 kfree(ldo->desc.name);
900 kfree(ldo);
901
902 return 0;
903}
904
905/*
906 * set dac bias
907 * common state changes:
908 * startup:
909 * off --> standby --> prepare --> on
910 * standby --> prepare --> on
911 *
912 * stop:
913 * on --> prepare --> standby
914 */
915static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
916 enum snd_soc_bias_level level)
917{
918 int ret;
919 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
920
921 switch (level) {
922 case SND_SOC_BIAS_ON:
923 case SND_SOC_BIAS_PREPARE:
924 break;
925 case SND_SOC_BIAS_STANDBY:
926 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
927 ret = regulator_bulk_enable(
928 ARRAY_SIZE(sgtl5000->supplies),
929 sgtl5000->supplies);
930 if (ret)
931 return ret;
932 udelay(10);
933 }
934
935 break;
936 case SND_SOC_BIAS_OFF:
937 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
938 sgtl5000->supplies);
939 break;
940 }
941
942 codec->dapm.bias_level = level;
943 return 0;
944}
945
946#define SGTL5000_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
947 SNDRV_PCM_FMTBIT_S20_3LE |\
948 SNDRV_PCM_FMTBIT_S24_LE |\
949 SNDRV_PCM_FMTBIT_S32_LE)
950
951static struct snd_soc_dai_ops sgtl5000_ops = {
952 .hw_params = sgtl5000_pcm_hw_params,
953 .digital_mute = sgtl5000_digital_mute,
954 .set_fmt = sgtl5000_set_dai_fmt,
955 .set_sysclk = sgtl5000_set_dai_sysclk,
956};
957
958static struct snd_soc_dai_driver sgtl5000_dai = {
959 .name = "sgtl5000",
960 .playback = {
961 .stream_name = "Playback",
962 .channels_min = 1,
963 .channels_max = 2,
964 /*
965 * only support 8~48K + 96K,
966 * TODO modify hw_param to support more
967 */
968 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
969 .formats = SGTL5000_FORMATS,
970 },
971 .capture = {
972 .stream_name = "Capture",
973 .channels_min = 1,
974 .channels_max = 2,
975 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
976 .formats = SGTL5000_FORMATS,
977 },
978 .ops = &sgtl5000_ops,
979 .symmetric_rates = 1,
980};
981
982static int sgtl5000_volatile_register(struct snd_soc_codec *codec,
983 unsigned int reg)
984{
985 switch (reg) {
986 case SGTL5000_CHIP_ID:
987 case SGTL5000_CHIP_ADCDAC_CTRL:
988 case SGTL5000_CHIP_ANA_STATUS:
989 return 1;
990 }
991
992 return 0;
993}
994
995#ifdef CONFIG_SUSPEND
996static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state)
997{
998 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
999
1000 return 0;
1001}
1002
1003/*
1004 * restore all sgtl5000 registers,
1005 * since a big hole between dap and regular registers,
1006 * we will restore them respectively.
1007 */
1008static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
1009{
1010 u16 *cache = codec->reg_cache;
1011 int i;
1012 int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1;
1013
1014 /* restore regular registers */
1015 for (i = 0; i < regular_regs; i++) {
1016 int reg = i << 1;
1017
1018 /* this regs depends on the others */
1019 if (reg == SGTL5000_CHIP_ANA_POWER ||
1020 reg == SGTL5000_CHIP_CLK_CTRL ||
1021 reg == SGTL5000_CHIP_LINREG_CTRL ||
1022 reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
1023 reg == SGTL5000_CHIP_CLK_CTRL)
1024 continue;
1025
1026 snd_soc_write(codec, reg, cache[i]);
1027 }
1028
1029 /* restore dap registers */
1030 for (i = SGTL5000_DAP_REG_OFFSET >> 1;
1031 i < SGTL5000_MAX_REG_OFFSET >> 1; i++) {
1032 int reg = i << 1;
1033
1034 snd_soc_write(codec, reg, cache[i]);
1035 }
1036
1037 /*
1038 * restore power and other regs according
1039 * to set_power() and set_clock()
1040 */
1041 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
1042 cache[SGTL5000_CHIP_LINREG_CTRL >> 1]);
1043
1044 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
1045 cache[SGTL5000_CHIP_ANA_POWER >> 1]);
1046
1047 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
1048 cache[SGTL5000_CHIP_CLK_CTRL >> 1]);
1049
1050 snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
1051 cache[SGTL5000_CHIP_REF_CTRL >> 1]);
1052
1053 snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1054 cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]);
1055 return 0;
1056}
1057
1058static int sgtl5000_resume(struct snd_soc_codec *codec)
1059{
1060 /* Bring the codec back up to standby to enable regulators */
1061 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1062
1063 /* Restore registers by cached in memory */
1064 sgtl5000_restore_regs(codec);
1065 return 0;
1066}
1067#else
1068#define sgtl5000_suspend NULL
1069#define sgtl5000_resume NULL
1070#endif /* CONFIG_SUSPEND */
1071
1072/*
1073 * sgtl5000 has 3 internal power supplies:
1074 * 1. VAG, normally set to vdda/2
1075 * 2. chargepump, set to different value
1076 * according to voltage of vdda and vddio
1077 * 3. line out VAG, normally set to vddio/2
1078 *
1079 * and should be set according to:
1080 * 1. vddd provided by external or not
1081 * 2. vdda and vddio voltage value. > 3.1v or not
1082 * 3. chip revision >=0x11 or not. If >=0x11, not use external vddd.
1083 */
1084static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1085{
1086 int vddd;
1087 int vdda;
1088 int vddio;
1089 u16 ana_pwr;
1090 u16 lreg_ctrl;
1091 int vag;
1092 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1093
1094 vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
1095 vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
1096 vddd = regulator_get_voltage(sgtl5000->supplies[VDDD].consumer);
1097
1098 vdda = vdda / 1000;
1099 vddio = vddio / 1000;
1100 vddd = vddd / 1000;
1101
1102 if (vdda <= 0 || vddio <= 0 || vddd < 0) {
1103 dev_err(codec->dev, "regulator voltage not set correctly\n");
1104
1105 return -EINVAL;
1106 }
1107
1108 /* according to datasheet, maximum voltage of supplies */
1109 if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
1110 dev_err(codec->dev,
1111 "exceed max voltage vdda %dmv vddio %dma vddd %dma\n",
1112 vdda, vddio, vddd);
1113
1114 return -EINVAL;
1115 }
1116
1117 /* reset value */
1118 ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
1119 ana_pwr |= SGTL5000_DAC_STEREO |
1120 SGTL5000_ADC_STEREO |
1121 SGTL5000_REFTOP_POWERUP;
1122 lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
1123
1124 if (vddio < 3100 && vdda < 3100) {
1125 /* enable internal oscillator used for charge pump */
1126 snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
1127 SGTL5000_INT_OSC_EN,
1128 SGTL5000_INT_OSC_EN);
1129 /* Enable VDDC charge pump */
1130 ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
1131 } else if (vddio >= 3100 && vdda >= 3100) {
1132 /*
1133 * if vddio and vddd > 3.1v,
1134 * charge pump should be clean before set ana_pwr
1135 */
1136 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1137 SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
1138
1139 /* VDDC use VDDIO rail */
1140 lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
1141 lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
1142 SGTL5000_VDDC_MAN_ASSN_SHIFT;
1143 }
1144
1145 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
1146
1147 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
1148
1149 /* set voltage to register */
1150 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1151 (0x1 << 4) - 1, 0x8);
1152
1153 /*
1154 * if vddd linear reg has been enabled,
1155 * simple digital supply should be clear to get
1156 * proper VDDD voltage.
1157 */
1158 if (ana_pwr & SGTL5000_LINEREG_D_POWERUP)
1159 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1160 SGTL5000_LINREG_SIMPLE_POWERUP,
1161 0);
1162 else
1163 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1164 SGTL5000_LINREG_SIMPLE_POWERUP |
1165 SGTL5000_STARTUP_POWERUP,
1166 0);
1167
1168 /*
1169 * set ADC/DAC VAG to vdda / 2,
1170 * should stay in range (0.8v, 1.575v)
1171 */
1172 vag = vdda / 2;
1173 if (vag <= SGTL5000_ANA_GND_BASE)
1174 vag = 0;
1175 else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP *
1176 (SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT))
1177 vag = SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT;
1178 else
1179 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
1180
1181 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1182 vag << SGTL5000_ANA_GND_SHIFT,
1183 vag << SGTL5000_ANA_GND_SHIFT);
1184
1185 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
1186 vag = vddio / 2;
1187 if (vag <= SGTL5000_LINE_OUT_GND_BASE)
1188 vag = 0;
1189 else if (vag >= SGTL5000_LINE_OUT_GND_BASE +
1190 SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
1191 vag = SGTL5000_LINE_OUT_GND_MAX;
1192 else
1193 vag = (vag - SGTL5000_LINE_OUT_GND_BASE) /
1194 SGTL5000_LINE_OUT_GND_STP;
1195
1196 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1197 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1198 SGTL5000_LINE_OUT_CURRENT_360u <<
1199 SGTL5000_LINE_OUT_CURRENT_SHIFT,
1200 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1201 SGTL5000_LINE_OUT_CURRENT_360u <<
1202 SGTL5000_LINE_OUT_CURRENT_SHIFT);
1203
1204 return 0;
1205}
1206
1207static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1208{
1209 u16 reg;
1210 int ret;
1211 int rev;
1212 int i;
1213 int external_vddd = 0;
1214 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1215
1216 for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++)
1217 sgtl5000->supplies[i].supply = supply_names[i];
1218
1219 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
1220 sgtl5000->supplies);
1221 if (!ret)
1222 external_vddd = 1;
1223 else {
1224 /* set internal ldo to 1.2v */
1225 int voltage = LDO_VOLTAGE;
1226
1227 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1228 if (ret) {
1229 dev_err(codec->dev,
1230 "Failed to register vddd internal supplies: %d\n",
1231 ret);
1232 return ret;
1233 }
1234
1235 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1236
1237 ret = regulator_bulk_get(codec->dev,
1238 ARRAY_SIZE(sgtl5000->supplies),
1239 sgtl5000->supplies);
1240
1241 if (ret) {
1242 ldo_regulator_remove(codec);
1243 dev_err(codec->dev,
1244 "Failed to request supplies: %d\n", ret);
1245
1246 return ret;
1247 }
1248 }
1249
1250 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1251 sgtl5000->supplies);
1252 if (ret)
1253 goto err_regulator_free;
1254
1255 /* wait for all power rails bring up */
1256 udelay(10);
1257
1258 /* read chip information */
1259 reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
1260 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1261 SGTL5000_PARTID_PART_ID) {
1262 dev_err(codec->dev,
1263 "Device with ID register %x is not a sgtl5000\n", reg);
1264 ret = -ENODEV;
1265 goto err_regulator_disable;
1266 }
1267
1268 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1269 dev_info(codec->dev, "sgtl5000 revision %d\n", rev);
1270
1271 /*
1272 * workaround for revision 0x11 and later,
1273 * roll back to use internal LDO
1274 */
1275 if (external_vddd && rev >= 0x11) {
1276 int voltage = LDO_VOLTAGE;
1277 /* disable all regulator first */
1278 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1279 sgtl5000->supplies);
1280 /* free VDDD regulator */
1281 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1282 sgtl5000->supplies);
1283
1284 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1285 if (ret)
1286 return ret;
1287
1288 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1289
1290 ret = regulator_bulk_get(codec->dev,
1291 ARRAY_SIZE(sgtl5000->supplies),
1292 sgtl5000->supplies);
1293 if (ret) {
1294 ldo_regulator_remove(codec);
1295 dev_err(codec->dev,
1296 "Failed to request supplies: %d\n", ret);
1297
1298 return ret;
1299 }
1300
1301 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1302 sgtl5000->supplies);
1303 if (ret)
1304 goto err_regulator_free;
1305
1306 /* wait for all power rails bring up */
1307 udelay(10);
1308 }
1309
1310 return 0;
1311
1312err_regulator_disable:
1313 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1314 sgtl5000->supplies);
1315err_regulator_free:
1316 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1317 sgtl5000->supplies);
1318 if (external_vddd)
1319 ldo_regulator_remove(codec);
1320 return ret;
1321
1322}
1323
1324static int sgtl5000_probe(struct snd_soc_codec *codec)
1325{
1326 int ret;
1327 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1328
1329 /* setup i2c data ops */
1330 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
1331 if (ret < 0) {
1332 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1333 return ret;
1334 }
1335
1336 ret = sgtl5000_enable_regulators(codec);
1337 if (ret)
1338 return ret;
1339
1340 /* power up sgtl5000 */
1341 ret = sgtl5000_set_power_regs(codec);
1342 if (ret)
1343 goto err;
1344
1345 /* enable small pop, introduce 400ms delay in turning off */
1346 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1347 SGTL5000_SMALL_POP,
1348 SGTL5000_SMALL_POP);
1349
1350 /* disable short cut detector */
1351 snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
1352
1353 /*
1354 * set i2s as default input of sound switch
1355 * TODO: add sound switch to control and dapm widge.
1356 */
1357 snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
1358 SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
1359 snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
1360 SGTL5000_ADC_EN | SGTL5000_DAC_EN);
1361
1362 /* enable dac volume ramp by default */
1363 snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
1364 SGTL5000_DAC_VOL_RAMP_EN |
1365 SGTL5000_DAC_MUTE_RIGHT |
1366 SGTL5000_DAC_MUTE_LEFT);
1367
1368 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
1369
1370 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1371 SGTL5000_HP_ZCD_EN |
1372 SGTL5000_ADC_ZCD_EN);
1373
1374 snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 0);
1375
1376 /*
1377 * disable DAP
1378 * TODO:
1379 * Enable DAP in kcontrol and dapm.
1380 */
1381 snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
1382
1383 /* leading to standby state */
1384 ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1385 if (ret)
1386 goto err;
1387
1388 snd_soc_add_controls(codec, sgtl5000_snd_controls,
1389 ARRAY_SIZE(sgtl5000_snd_controls));
1390
1391 snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
1392 ARRAY_SIZE(sgtl5000_dapm_widgets));
1393
1394 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1395 ARRAY_SIZE(audio_map));
1396
1397 snd_soc_dapm_new_widgets(&codec->dapm);
1398
1399 return 0;
1400
1401err:
1402 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1403 sgtl5000->supplies);
1404 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1405 sgtl5000->supplies);
1406 ldo_regulator_remove(codec);
1407
1408 return ret;
1409}
1410
1411static int sgtl5000_remove(struct snd_soc_codec *codec)
1412{
1413 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1414
1415 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
1416
1417 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1418 sgtl5000->supplies);
1419 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1420 sgtl5000->supplies);
1421 ldo_regulator_remove(codec);
1422
1423 return 0;
1424}
1425
1426static struct snd_soc_codec_driver sgtl5000_driver = {
1427 .probe = sgtl5000_probe,
1428 .remove = sgtl5000_remove,
1429 .suspend = sgtl5000_suspend,
1430 .resume = sgtl5000_resume,
1431 .set_bias_level = sgtl5000_set_bias_level,
1432 .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
1433 .reg_word_size = sizeof(u16),
1434 .reg_cache_step = 2,
1435 .reg_cache_default = sgtl5000_regs,
1436 .volatile_register = sgtl5000_volatile_register,
1437};
1438
1439static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
1440 const struct i2c_device_id *id)
1441{
1442 struct sgtl5000_priv *sgtl5000;
1443 int ret;
1444
1445 sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL);
1446 if (!sgtl5000)
1447 return -ENOMEM;
1448
1449 /*
1450 * copy DAP default values to default value array.
1451 * sgtl5000 register space has a big hole, merge it
1452 * at init phase makes life easy.
1453 * FIXME: should we drop 'const' of sgtl5000_regs?
1454 */
1455 memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)),
1456 sgtl5000_dap_regs,
1457 SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET);
1458
1459 i2c_set_clientdata(client, sgtl5000);
1460
1461 ret = snd_soc_register_codec(&client->dev,
1462 &sgtl5000_driver, &sgtl5000_dai, 1);
1463 if (ret) {
1464 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1465 kfree(sgtl5000);
1466 return ret;
1467 }
1468
1469 return 0;
1470}
1471
1472static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
1473{
1474 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1475
1476 snd_soc_unregister_codec(&client->dev);
1477
1478 kfree(sgtl5000);
1479 return 0;
1480}
1481
1482static const struct i2c_device_id sgtl5000_id[] = {
1483 {"sgtl5000", 0},
1484 {},
1485};
1486
1487MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1488
1489static struct i2c_driver sgtl5000_i2c_driver = {
1490 .driver = {
1491 .name = "sgtl5000",
1492 .owner = THIS_MODULE,
1493 },
1494 .probe = sgtl5000_i2c_probe,
1495 .remove = __devexit_p(sgtl5000_i2c_remove),
1496 .id_table = sgtl5000_id,
1497};
1498
1499static int __init sgtl5000_modinit(void)
1500{
1501 return i2c_add_driver(&sgtl5000_i2c_driver);
1502}
1503module_init(sgtl5000_modinit);
1504
1505static void __exit sgtl5000_exit(void)
1506{
1507 i2c_del_driver(&sgtl5000_i2c_driver);
1508}
1509module_exit(sgtl5000_exit);
1510
1511MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
1512MODULE_AUTHOR("Zeng Zhaoming <zhaoming.zeng@freescale.com>");
1513MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
new file mode 100644
index 000000000000..eec3ab368f39
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.h
@@ -0,0 +1,400 @@
1/*
2 * sgtl5000.h - SGTL5000 audio codec interface
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _SGTL5000_H
12#define _SGTL5000_H
13
14/*
15 * Register values.
16 */
17#define SGTL5000_CHIP_ID 0x0000
18#define SGTL5000_CHIP_DIG_POWER 0x0002
19#define SGTL5000_CHIP_CLK_CTRL 0x0004
20#define SGTL5000_CHIP_I2S_CTRL 0x0006
21#define SGTL5000_CHIP_SSS_CTRL 0x000a
22#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e
23#define SGTL5000_CHIP_DAC_VOL 0x0010
24#define SGTL5000_CHIP_PAD_STRENGTH 0x0014
25#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020
26#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022
27#define SGTL5000_CHIP_ANA_CTRL 0x0024
28#define SGTL5000_CHIP_LINREG_CTRL 0x0026
29#define SGTL5000_CHIP_REF_CTRL 0x0028
30#define SGTL5000_CHIP_MIC_CTRL 0x002a
31#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c
32#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e
33#define SGTL5000_CHIP_ANA_POWER 0x0030
34#define SGTL5000_CHIP_PLL_CTRL 0x0032
35#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034
36#define SGTL5000_CHIP_ANA_STATUS 0x0036
37#define SGTL5000_CHIP_SHORT_CTRL 0x003c
38#define SGTL5000_CHIP_ANA_TEST2 0x003a
39#define SGTL5000_DAP_CTRL 0x0100
40#define SGTL5000_DAP_PEQ 0x0102
41#define SGTL5000_DAP_BASS_ENHANCE 0x0104
42#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106
43#define SGTL5000_DAP_AUDIO_EQ 0x0108
44#define SGTL5000_DAP_SURROUND 0x010a
45#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c
46#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e
47#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110
48#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116
49#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118
50#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a
51#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c
52#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e
53#define SGTL5000_DAP_MAIN_CHAN 0x0120
54#define SGTL5000_DAP_MIX_CHAN 0x0122
55#define SGTL5000_DAP_AVC_CTRL 0x0124
56#define SGTL5000_DAP_AVC_THRESHOLD 0x0126
57#define SGTL5000_DAP_AVC_ATTACK 0x0128
58#define SGTL5000_DAP_AVC_DECAY 0x012a
59#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c
60#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e
61#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130
62#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132
63#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134
64#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136
65#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138
66#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a
67
68/*
69 * Field Definitions.
70 */
71
72/*
73 * SGTL5000_CHIP_ID
74 */
75#define SGTL5000_PARTID_MASK 0xff00
76#define SGTL5000_PARTID_SHIFT 8
77#define SGTL5000_PARTID_WIDTH 8
78#define SGTL5000_PARTID_PART_ID 0xa0
79#define SGTL5000_REVID_MASK 0x00ff
80#define SGTL5000_REVID_SHIFT 0
81#define SGTL5000_REVID_WIDTH 8
82
83/*
84 * SGTL5000_CHIP_DIG_POWER
85 */
86#define SGTL5000_ADC_EN 0x0040
87#define SGTL5000_DAC_EN 0x0020
88#define SGTL5000_DAP_POWERUP 0x0010
89#define SGTL5000_I2S_OUT_POWERUP 0x0002
90#define SGTL5000_I2S_IN_POWERUP 0x0001
91
92/*
93 * SGTL5000_CHIP_CLK_CTRL
94 */
95#define SGTL5000_RATE_MODE_MASK 0x0030
96#define SGTL5000_RATE_MODE_SHIFT 4
97#define SGTL5000_RATE_MODE_WIDTH 2
98#define SGTL5000_RATE_MODE_DIV_1 0
99#define SGTL5000_RATE_MODE_DIV_2 1
100#define SGTL5000_RATE_MODE_DIV_4 2
101#define SGTL5000_RATE_MODE_DIV_6 3
102#define SGTL5000_SYS_FS_MASK 0x000c
103#define SGTL5000_SYS_FS_SHIFT 2
104#define SGTL5000_SYS_FS_WIDTH 2
105#define SGTL5000_SYS_FS_32k 0x0
106#define SGTL5000_SYS_FS_44_1k 0x1
107#define SGTL5000_SYS_FS_48k 0x2
108#define SGTL5000_SYS_FS_96k 0x3
109#define SGTL5000_MCLK_FREQ_MASK 0x0003
110#define SGTL5000_MCLK_FREQ_SHIFT 0
111#define SGTL5000_MCLK_FREQ_WIDTH 2
112#define SGTL5000_MCLK_FREQ_256FS 0x0
113#define SGTL5000_MCLK_FREQ_384FS 0x1
114#define SGTL5000_MCLK_FREQ_512FS 0x2
115#define SGTL5000_MCLK_FREQ_PLL 0x3
116
117/*
118 * SGTL5000_CHIP_I2S_CTRL
119 */
120#define SGTL5000_I2S_SCLKFREQ_MASK 0x0100
121#define SGTL5000_I2S_SCLKFREQ_SHIFT 8
122#define SGTL5000_I2S_SCLKFREQ_WIDTH 1
123#define SGTL5000_I2S_SCLKFREQ_64FS 0x0
124#define SGTL5000_I2S_SCLKFREQ_32FS 0x1 /* Not for RJ mode */
125#define SGTL5000_I2S_MASTER 0x0080
126#define SGTL5000_I2S_SCLK_INV 0x0040
127#define SGTL5000_I2S_DLEN_MASK 0x0030
128#define SGTL5000_I2S_DLEN_SHIFT 4
129#define SGTL5000_I2S_DLEN_WIDTH 2
130#define SGTL5000_I2S_DLEN_32 0x0
131#define SGTL5000_I2S_DLEN_24 0x1
132#define SGTL5000_I2S_DLEN_20 0x2
133#define SGTL5000_I2S_DLEN_16 0x3
134#define SGTL5000_I2S_MODE_MASK 0x000c
135#define SGTL5000_I2S_MODE_SHIFT 2
136#define SGTL5000_I2S_MODE_WIDTH 2
137#define SGTL5000_I2S_MODE_I2S_LJ 0x0
138#define SGTL5000_I2S_MODE_RJ 0x1
139#define SGTL5000_I2S_MODE_PCM 0x2
140#define SGTL5000_I2S_LRALIGN 0x0002
141#define SGTL5000_I2S_LRPOL 0x0001 /* set for which mode */
142
143/*
144 * SGTL5000_CHIP_SSS_CTRL
145 */
146#define SGTL5000_DAP_MIX_LRSWAP 0x4000
147#define SGTL5000_DAP_LRSWAP 0x2000
148#define SGTL5000_DAC_LRSWAP 0x1000
149#define SGTL5000_I2S_OUT_LRSWAP 0x0400
150#define SGTL5000_DAP_MIX_SEL_MASK 0x0300
151#define SGTL5000_DAP_MIX_SEL_SHIFT 8
152#define SGTL5000_DAP_MIX_SEL_WIDTH 2
153#define SGTL5000_DAP_MIX_SEL_ADC 0x0
154#define SGTL5000_DAP_MIX_SEL_I2S_IN 0x1
155#define SGTL5000_DAP_SEL_MASK 0x00c0
156#define SGTL5000_DAP_SEL_SHIFT 6
157#define SGTL5000_DAP_SEL_WIDTH 2
158#define SGTL5000_DAP_SEL_ADC 0x0
159#define SGTL5000_DAP_SEL_I2S_IN 0x1
160#define SGTL5000_DAC_SEL_MASK 0x0030
161#define SGTL5000_DAC_SEL_SHIFT 4
162#define SGTL5000_DAC_SEL_WIDTH 2
163#define SGTL5000_DAC_SEL_ADC 0x0
164#define SGTL5000_DAC_SEL_I2S_IN 0x1
165#define SGTL5000_DAC_SEL_DAP 0x3
166#define SGTL5000_I2S_OUT_SEL_MASK 0x0003
167#define SGTL5000_I2S_OUT_SEL_SHIFT 0
168#define SGTL5000_I2S_OUT_SEL_WIDTH 2
169#define SGTL5000_I2S_OUT_SEL_ADC 0x0
170#define SGTL5000_I2S_OUT_SEL_I2S_IN 0x1
171#define SGTL5000_I2S_OUT_SEL_DAP 0x3
172
173/*
174 * SGTL5000_CHIP_ADCDAC_CTRL
175 */
176#define SGTL5000_VOL_BUSY_DAC_RIGHT 0x2000
177#define SGTL5000_VOL_BUSY_DAC_LEFT 0x1000
178#define SGTL5000_DAC_VOL_RAMP_EN 0x0200
179#define SGTL5000_DAC_VOL_RAMP_EXPO 0x0100
180#define SGTL5000_DAC_MUTE_RIGHT 0x0008
181#define SGTL5000_DAC_MUTE_LEFT 0x0004
182#define SGTL5000_ADC_HPF_FREEZE 0x0002
183#define SGTL5000_ADC_HPF_BYPASS 0x0001
184
185/*
186 * SGTL5000_CHIP_DAC_VOL
187 */
188#define SGTL5000_DAC_VOL_RIGHT_MASK 0xff00
189#define SGTL5000_DAC_VOL_RIGHT_SHIFT 8
190#define SGTL5000_DAC_VOL_RIGHT_WIDTH 8
191#define SGTL5000_DAC_VOL_LEFT_MASK 0x00ff
192#define SGTL5000_DAC_VOL_LEFT_SHIFT 0
193#define SGTL5000_DAC_VOL_LEFT_WIDTH 8
194
195/*
196 * SGTL5000_CHIP_PAD_STRENGTH
197 */
198#define SGTL5000_PAD_I2S_LRCLK_MASK 0x0300
199#define SGTL5000_PAD_I2S_LRCLK_SHIFT 8
200#define SGTL5000_PAD_I2S_LRCLK_WIDTH 2
201#define SGTL5000_PAD_I2S_SCLK_MASK 0x00c0
202#define SGTL5000_PAD_I2S_SCLK_SHIFT 6
203#define SGTL5000_PAD_I2S_SCLK_WIDTH 2
204#define SGTL5000_PAD_I2S_DOUT_MASK 0x0030
205#define SGTL5000_PAD_I2S_DOUT_SHIFT 4
206#define SGTL5000_PAD_I2S_DOUT_WIDTH 2
207#define SGTL5000_PAD_I2C_SDA_MASK 0x000c
208#define SGTL5000_PAD_I2C_SDA_SHIFT 2
209#define SGTL5000_PAD_I2C_SDA_WIDTH 2
210#define SGTL5000_PAD_I2C_SCL_MASK 0x0003
211#define SGTL5000_PAD_I2C_SCL_SHIFT 0
212#define SGTL5000_PAD_I2C_SCL_WIDTH 2
213
214/*
215 * SGTL5000_CHIP_ANA_ADC_CTRL
216 */
217#define SGTL5000_ADC_VOL_M6DB 0x0100
218#define SGTL5000_ADC_VOL_RIGHT_MASK 0x00f0
219#define SGTL5000_ADC_VOL_RIGHT_SHIFT 4
220#define SGTL5000_ADC_VOL_RIGHT_WIDTH 4
221#define SGTL5000_ADC_VOL_LEFT_MASK 0x000f
222#define SGTL5000_ADC_VOL_LEFT_SHIFT 0
223#define SGTL5000_ADC_VOL_LEFT_WIDTH 4
224
225/*
226 * SGTL5000_CHIP_ANA_HP_CTRL
227 */
228#define SGTL5000_HP_VOL_RIGHT_MASK 0x7f00
229#define SGTL5000_HP_VOL_RIGHT_SHIFT 8
230#define SGTL5000_HP_VOL_RIGHT_WIDTH 7
231#define SGTL5000_HP_VOL_LEFT_MASK 0x007f
232#define SGTL5000_HP_VOL_LEFT_SHIFT 0
233#define SGTL5000_HP_VOL_LEFT_WIDTH 7
234
235/*
236 * SGTL5000_CHIP_ANA_CTRL
237 */
238#define SGTL5000_LINE_OUT_MUTE 0x0100
239#define SGTL5000_HP_SEL_MASK 0x0040
240#define SGTL5000_HP_SEL_SHIFT 6
241#define SGTL5000_HP_SEL_WIDTH 1
242#define SGTL5000_HP_SEL_DAC 0x0
243#define SGTL5000_HP_SEL_LINE_IN 0x1
244#define SGTL5000_HP_ZCD_EN 0x0020
245#define SGTL5000_HP_MUTE 0x0010
246#define SGTL5000_ADC_SEL_MASK 0x0004
247#define SGTL5000_ADC_SEL_SHIFT 2
248#define SGTL5000_ADC_SEL_WIDTH 1
249#define SGTL5000_ADC_SEL_MIC 0x0
250#define SGTL5000_ADC_SEL_LINE_IN 0x1
251#define SGTL5000_ADC_ZCD_EN 0x0002
252#define SGTL5000_ADC_MUTE 0x0001
253
254/*
255 * SGTL5000_CHIP_LINREG_CTRL
256 */
257#define SGTL5000_VDDC_MAN_ASSN_MASK 0x0040
258#define SGTL5000_VDDC_MAN_ASSN_SHIFT 6
259#define SGTL5000_VDDC_MAN_ASSN_WIDTH 1
260#define SGTL5000_VDDC_MAN_ASSN_VDDA 0x0
261#define SGTL5000_VDDC_MAN_ASSN_VDDIO 0x1
262#define SGTL5000_VDDC_ASSN_OVRD 0x0020
263#define SGTL5000_LINREG_VDDD_MASK 0x000f
264#define SGTL5000_LINREG_VDDD_SHIFT 0
265#define SGTL5000_LINREG_VDDD_WIDTH 4
266
267/*
268 * SGTL5000_CHIP_REF_CTRL
269 */
270#define SGTL5000_ANA_GND_MASK 0x01f0
271#define SGTL5000_ANA_GND_SHIFT 4
272#define SGTL5000_ANA_GND_WIDTH 5
273#define SGTL5000_ANA_GND_BASE 800 /* mv */
274#define SGTL5000_ANA_GND_STP 25 /*mv */
275#define SGTL5000_BIAS_CTRL_MASK 0x000e
276#define SGTL5000_BIAS_CTRL_SHIFT 1
277#define SGTL5000_BIAS_CTRL_WIDTH 3
278#define SGTL5000_SMALL_POP 0x0001
279
280/*
281 * SGTL5000_CHIP_MIC_CTRL
282 */
283#define SGTL5000_BIAS_R_MASK 0x0200
284#define SGTL5000_BIAS_R_SHIFT 8
285#define SGTL5000_BIAS_R_WIDTH 2
286#define SGTL5000_BIAS_R_off 0x0
287#define SGTL5000_BIAS_R_2K 0x1
288#define SGTL5000_BIAS_R_4k 0x2
289#define SGTL5000_BIAS_R_8k 0x3
290#define SGTL5000_BIAS_VOLT_MASK 0x0070
291#define SGTL5000_BIAS_VOLT_SHIFT 4
292#define SGTL5000_BIAS_VOLT_WIDTH 3
293#define SGTL5000_MIC_GAIN_MASK 0x0003
294#define SGTL5000_MIC_GAIN_SHIFT 0
295#define SGTL5000_MIC_GAIN_WIDTH 2
296
297/*
298 * SGTL5000_CHIP_LINE_OUT_CTRL
299 */
300#define SGTL5000_LINE_OUT_CURRENT_MASK 0x0f00
301#define SGTL5000_LINE_OUT_CURRENT_SHIFT 8
302#define SGTL5000_LINE_OUT_CURRENT_WIDTH 4
303#define SGTL5000_LINE_OUT_CURRENT_180u 0x0
304#define SGTL5000_LINE_OUT_CURRENT_270u 0x1
305#define SGTL5000_LINE_OUT_CURRENT_360u 0x3
306#define SGTL5000_LINE_OUT_CURRENT_450u 0x7
307#define SGTL5000_LINE_OUT_CURRENT_540u 0xf
308#define SGTL5000_LINE_OUT_GND_MASK 0x003f
309#define SGTL5000_LINE_OUT_GND_SHIFT 0
310#define SGTL5000_LINE_OUT_GND_WIDTH 6
311#define SGTL5000_LINE_OUT_GND_BASE 800 /* mv */
312#define SGTL5000_LINE_OUT_GND_STP 25
313#define SGTL5000_LINE_OUT_GND_MAX 0x23
314
315/*
316 * SGTL5000_CHIP_LINE_OUT_VOL
317 */
318#define SGTL5000_LINE_OUT_VOL_RIGHT_MASK 0x1f00
319#define SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT 8
320#define SGTL5000_LINE_OUT_VOL_RIGHT_WIDTH 5
321#define SGTL5000_LINE_OUT_VOL_LEFT_MASK 0x001f
322#define SGTL5000_LINE_OUT_VOL_LEFT_SHIFT 0
323#define SGTL5000_LINE_OUT_VOL_LEFT_WIDTH 5
324
325/*
326 * SGTL5000_CHIP_ANA_POWER
327 */
328#define SGTL5000_DAC_STEREO 0x4000
329#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000
330#define SGTL5000_STARTUP_POWERUP 0x1000
331#define SGTL5000_VDDC_CHRGPMP_POWERUP 0x0800
332#define SGTL5000_PLL_POWERUP 0x0400
333#define SGTL5000_LINEREG_D_POWERUP 0x0200
334#define SGTL5000_VCOAMP_POWERUP 0x0100
335#define SGTL5000_VAG_POWERUP 0x0080
336#define SGTL5000_ADC_STEREO 0x0040
337#define SGTL5000_REFTOP_POWERUP 0x0020
338#define SGTL5000_HP_POWERUP 0x0010
339#define SGTL5000_DAC_POWERUP 0x0008
340#define SGTL5000_CAPLESS_HP_POWERUP 0x0004
341#define SGTL5000_ADC_POWERUP 0x0002
342#define SGTL5000_LINE_OUT_POWERUP 0x0001
343
344/*
345 * SGTL5000_CHIP_PLL_CTRL
346 */
347#define SGTL5000_PLL_INT_DIV_MASK 0xf800
348#define SGTL5000_PLL_INT_DIV_SHIFT 11
349#define SGTL5000_PLL_INT_DIV_WIDTH 5
350#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700
351#define SGTL5000_PLL_FRAC_DIV_SHIFT 0
352#define SGTL5000_PLL_FRAC_DIV_WIDTH 11
353
354/*
355 * SGTL5000_CHIP_CLK_TOP_CTRL
356 */
357#define SGTL5000_INT_OSC_EN 0x0800
358#define SGTL5000_INPUT_FREQ_DIV2 0x0008
359
360/*
361 * SGTL5000_CHIP_ANA_STATUS
362 */
363#define SGTL5000_HP_LRSHORT 0x0200
364#define SGTL5000_CAPLESS_SHORT 0x0100
365#define SGTL5000_PLL_LOCKED 0x0010
366
367/*
368 * SGTL5000_CHIP_SHORT_CTRL
369 */
370#define SGTL5000_LVLADJR_MASK 0x7000
371#define SGTL5000_LVLADJR_SHIFT 12
372#define SGTL5000_LVLADJR_WIDTH 3
373#define SGTL5000_LVLADJL_MASK 0x0700
374#define SGTL5000_LVLADJL_SHIFT 8
375#define SGTL5000_LVLADJL_WIDTH 3
376#define SGTL5000_LVLADJC_MASK 0x0070
377#define SGTL5000_LVLADJC_SHIFT 4
378#define SGTL5000_LVLADJC_WIDTH 3
379#define SGTL5000_LR_SHORT_MOD_MASK 0x000c
380#define SGTL5000_LR_SHORT_MOD_SHIFT 2
381#define SGTL5000_LR_SHORT_MOD_WIDTH 2
382#define SGTL5000_CM_SHORT_MOD_MASK 0x0003
383#define SGTL5000_CM_SHORT_MOD_SHIFT 0
384#define SGTL5000_CM_SHORT_MOD_WIDTH 2
385
386/*
387 *SGTL5000_CHIP_ANA_TEST2
388 */
389#define SGTL5000_MONO_DAC 0x1000
390
391/*
392 * SGTL5000_DAP_CTRL
393 */
394#define SGTL5000_DAP_MIX_EN 0x0010
395#define SGTL5000_DAP_EN 0x0001
396
397#define SGTL5000_SYSCLK 0x00
398#define SGTL5000_LRCLK 0x01
399
400#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 40e285df9ae5..2a30eae1881c 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -34,17 +34,135 @@
34#include <sound/soc-dapm.h> 34#include <sound/soc-dapm.h>
35#include <sound/initval.h> 35#include <sound/initval.h>
36#include <sound/tlv.h> 36#include <sound/tlv.h>
37#include <sound/jack.h>
37#include "sn95031.h" 38#include "sn95031.h"
38 39
39#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) 40#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
40#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 41#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
41 42
43/* adc helper functions */
44
45/* enables mic bias voltage */
46static void sn95031_enable_mic_bias(struct snd_soc_codec *codec)
47{
48 snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0));
49 snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2));
50}
51
52/* Enable/Disable the ADC depending on the argument */
53static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
54{
55 int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
56
57 if (val) {
58 /* Enable and start the ADC */
59 value |= (SN95031_ADC_ENBL | SN95031_ADC_START);
60 value &= (~SN95031_ADC_NO_LOOP);
61 } else {
62 /* Just stop the ADC */
63 value &= (~SN95031_ADC_START);
64 }
65 snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value);
66}
67
42/* 68/*
43 * todo: 69 * finds an empty channel for conversion
44 * capture paths 70 * If the ADC is not enabled then start using 0th channel
45 * jack detection 71 * itself. Otherwise find an empty channel by looking for a
46 * PM functions 72 * channel in which the stopbit is set to 1. returns the index
73 * of the first free channel if succeeds or an error code.
74 *
75 * Context: can sleep
76 *
47 */ 77 */
78static int find_free_channel(struct snd_soc_codec *sn95031_codec)
79{
80 int ret = 0, i, value;
81
82 /* check whether ADC is enabled */
83 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
84
85 if ((value & SN95031_ADC_ENBL) == 0)
86 return 0;
87
88 /* ADC is already enabled; Looking for an empty channel */
89 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
90 value = snd_soc_read(sn95031_codec,
91 SN95031_ADC_CHNL_START_ADDR + i);
92 if (value & SN95031_STOPBIT_MASK) {
93 ret = i;
94 break;
95 }
96 }
97 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret;
98}
99
100/* Initialize the ADC for reading micbias values. Can sleep. */
101static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
102{
103 int base_addr, chnl_addr;
104 int value;
105 static int channel_index;
106
107 /* Index of the first channel in which the stop bit is set */
108 channel_index = find_free_channel(sn95031_codec);
109 if (channel_index < 0) {
110 pr_err("No free ADC channels");
111 return channel_index;
112 }
113
114 base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index;
115
116 if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) {
117 /* Reset stop bit for channels other than 0 and 12 */
118 value = snd_soc_read(sn95031_codec, base_addr);
119 /* Set the stop bit to zero */
120 snd_soc_write(sn95031_codec, base_addr, value & 0xEF);
121 /* Index of the first free channel */
122 base_addr++;
123 channel_index++;
124 }
125
126 /* Since this is the last channel, set the stop bit
127 to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
128 snd_soc_write(sn95031_codec, base_addr,
129 SN95031_AUDIO_DETECT_CODE | 0x10);
130
131 chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index;
132 pr_debug("mid_initialize : %x", chnl_addr);
133 configure_adc(sn95031_codec, 1);
134 return chnl_addr;
135}
136
137
138/* reads the ADC registers and gets the mic bias value in mV. */
139static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
140{
141 u16 adc_adr = sn95031_initialize_adc(codec);
142 u16 adc_val1, adc_val2;
143 unsigned int mic_bias;
144
145 sn95031_enable_mic_bias(codec);
146
147 /* Enable the sound card for conversion before reading */
148 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05);
149 /* Re-toggle the RRDATARD bit */
150 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04);
151
152 /* Read the higher bits of data */
153 msleep(1000);
154 adc_val1 = snd_soc_read(codec, adc_adr);
155 adc_adr++;
156 adc_val2 = snd_soc_read(codec, adc_adr);
157
158 /* Adding lower two bits to the higher bits */
159 mic_bias = (adc_val1 << 2) + (adc_val2 & 3);
160 mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000;
161 pr_debug("mic bias = %dmV\n", mic_bias);
162 return mic_bias;
163}
164EXPORT_SYMBOL_GPL(sn95031_get_mic_bias);
165/*end - adc helper functions */
48 166
49static inline unsigned int sn95031_read(struct snd_soc_codec *codec, 167static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
50 unsigned int reg) 168 unsigned int reg)
@@ -241,7 +359,7 @@ static const struct snd_kcontrol_new sn95031_input4_mux_control =
241static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"}; 359static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
242 360
243/* 0dB to 30dB in 10dB steps */ 361/* 0dB to 30dB in 10dB steps */
244static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 30); 362static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0);
245 363
246static const struct soc_enum sn95031_micmode1_enum = 364static const struct soc_enum sn95031_micmode1_enum =
247 SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text); 365 SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text);
@@ -401,6 +519,8 @@ static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
401 519
402static const struct snd_soc_dapm_route sn95031_audio_map[] = { 520static const struct snd_soc_dapm_route sn95031_audio_map[] = {
403 /* headset and earpiece map */ 521 /* headset and earpiece map */
522 { "HPOUTL", NULL, "Headset Rail"},
523 { "HPOUTR", NULL, "Headset Rail"},
404 { "HPOUTL", NULL, "Headset Left Playback" }, 524 { "HPOUTL", NULL, "Headset Left Playback" },
405 { "HPOUTR", NULL, "Headset Right Playback" }, 525 { "HPOUTR", NULL, "Headset Right Playback" },
406 { "EPOUT", NULL, "Earpiece Playback" }, 526 { "EPOUT", NULL, "Earpiece Playback" },
@@ -409,18 +529,16 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = {
409 { "Earpiece Playback", NULL, "Headset Left Filter"}, 529 { "Earpiece Playback", NULL, "Headset Left Filter"},
410 { "Headset Left Filter", NULL, "HSDAC Left"}, 530 { "Headset Left Filter", NULL, "HSDAC Left"},
411 { "Headset Right Filter", NULL, "HSDAC Right"}, 531 { "Headset Right Filter", NULL, "HSDAC Right"},
412 { "HSDAC Left", NULL, "Headset Rail"},
413 { "HSDAC Right", NULL, "Headset Rail"},
414 532
415 /* speaker map */ 533 /* speaker map */
534 { "IHFOUTL", NULL, "Speaker Rail"},
535 { "IHFOUTR", NULL, "Speaker Rail"},
416 { "IHFOUTL", "NULL", "Speaker Left Playback"}, 536 { "IHFOUTL", "NULL", "Speaker Left Playback"},
417 { "IHFOUTR", "NULL", "Speaker Right Playback"}, 537 { "IHFOUTR", "NULL", "Speaker Right Playback"},
418 { "Speaker Left Playback", NULL, "Speaker Left Filter"}, 538 { "Speaker Left Playback", NULL, "Speaker Left Filter"},
419 { "Speaker Right Playback", NULL, "Speaker Right Filter"}, 539 { "Speaker Right Playback", NULL, "Speaker Right Filter"},
420 { "Speaker Left Filter", NULL, "IHFDAC Left"}, 540 { "Speaker Left Filter", NULL, "IHFDAC Left"},
421 { "Speaker Right Filter", NULL, "IHFDAC Right"}, 541 { "Speaker Right Filter", NULL, "IHFDAC Right"},
422 { "IHFDAC Left", NULL, "Speaker Rail"},
423 { "IHFDAC Right", NULL, "Speaker Rail"},
424 542
425 /* vibra map */ 543 /* vibra map */
426 { "VIB1OUT", NULL, "Vibra1 Playback"}, 544 { "VIB1OUT", NULL, "Vibra1 Playback"},
@@ -484,30 +602,30 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = {
484 { "Txpath2 Capture Route", "ADC Right", "ADC Right"}, 602 { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
485 { "Txpath3 Capture Route", "ADC Right", "ADC Right"}, 603 { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
486 { "Txpath4 Capture Route", "ADC Right", "ADC Right"}, 604 { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
487 { "Txpath1 Capture Route", NULL, "DMIC1"}, 605 { "Txpath1 Capture Route", "DMIC1", "DMIC1"},
488 { "Txpath2 Capture Route", NULL, "DMIC1"}, 606 { "Txpath2 Capture Route", "DMIC1", "DMIC1"},
489 { "Txpath3 Capture Route", NULL, "DMIC1"}, 607 { "Txpath3 Capture Route", "DMIC1", "DMIC1"},
490 { "Txpath4 Capture Route", NULL, "DMIC1"}, 608 { "Txpath4 Capture Route", "DMIC1", "DMIC1"},
491 { "Txpath1 Capture Route", NULL, "DMIC2"}, 609 { "Txpath1 Capture Route", "DMIC2", "DMIC2"},
492 { "Txpath2 Capture Route", NULL, "DMIC2"}, 610 { "Txpath2 Capture Route", "DMIC2", "DMIC2"},
493 { "Txpath3 Capture Route", NULL, "DMIC2"}, 611 { "Txpath3 Capture Route", "DMIC2", "DMIC2"},
494 { "Txpath4 Capture Route", NULL, "DMIC2"}, 612 { "Txpath4 Capture Route", "DMIC2", "DMIC2"},
495 { "Txpath1 Capture Route", NULL, "DMIC3"}, 613 { "Txpath1 Capture Route", "DMIC3", "DMIC3"},
496 { "Txpath2 Capture Route", NULL, "DMIC3"}, 614 { "Txpath2 Capture Route", "DMIC3", "DMIC3"},
497 { "Txpath3 Capture Route", NULL, "DMIC3"}, 615 { "Txpath3 Capture Route", "DMIC3", "DMIC3"},
498 { "Txpath4 Capture Route", NULL, "DMIC3"}, 616 { "Txpath4 Capture Route", "DMIC3", "DMIC3"},
499 { "Txpath1 Capture Route", NULL, "DMIC4"}, 617 { "Txpath1 Capture Route", "DMIC4", "DMIC4"},
500 { "Txpath2 Capture Route", NULL, "DMIC4"}, 618 { "Txpath2 Capture Route", "DMIC4", "DMIC4"},
501 { "Txpath3 Capture Route", NULL, "DMIC4"}, 619 { "Txpath3 Capture Route", "DMIC4", "DMIC4"},
502 { "Txpath4 Capture Route", NULL, "DMIC4"}, 620 { "Txpath4 Capture Route", "DMIC4", "DMIC4"},
503 { "Txpath1 Capture Route", NULL, "DMIC5"}, 621 { "Txpath1 Capture Route", "DMIC5", "DMIC5"},
504 { "Txpath2 Capture Route", NULL, "DMIC5"}, 622 { "Txpath2 Capture Route", "DMIC5", "DMIC5"},
505 { "Txpath3 Capture Route", NULL, "DMIC5"}, 623 { "Txpath3 Capture Route", "DMIC5", "DMIC5"},
506 { "Txpath4 Capture Route", NULL, "DMIC5"}, 624 { "Txpath4 Capture Route", "DMIC5", "DMIC5"},
507 { "Txpath1 Capture Route", NULL, "DMIC6"}, 625 { "Txpath1 Capture Route", "DMIC6", "DMIC6"},
508 { "Txpath2 Capture Route", NULL, "DMIC6"}, 626 { "Txpath2 Capture Route", "DMIC6", "DMIC6"},
509 { "Txpath3 Capture Route", NULL, "DMIC6"}, 627 { "Txpath3 Capture Route", "DMIC6", "DMIC6"},
510 { "Txpath4 Capture Route", NULL, "DMIC6"}, 628 { "Txpath4 Capture Route", "DMIC6", "DMIC6"},
511 629
512 /* tx path */ 630 /* tx path */
513 { "TX1 Enable", NULL, "Txpath1 Capture Route"}, 631 { "TX1 Enable", NULL, "Txpath1 Capture Route"},
@@ -649,6 +767,61 @@ struct snd_soc_dai_driver sn95031_dais[] = {
649}, 767},
650}; 768};
651 769
770static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
771{
772 snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
773}
774
775static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
776{
777 snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
778 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
779}
780
781static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack)
782{
783 int micbias = sn95031_get_mic_bias(mfld_jack->codec);
784
785 int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
786
787 pr_debug("jack type detected = %d\n", jack_type);
788 if (jack_type == SND_JACK_HEADSET)
789 sn95031_enable_jack_btn(mfld_jack->codec);
790 return jack_type;
791}
792
793void sn95031_jack_detection(struct mfld_jack_data *jack_data)
794{
795 unsigned int status;
796 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
797
798 pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
799 if (jack_data->intr_id & 0x1) {
800 pr_debug("short_push detected\n");
801 status = SND_JACK_HEADSET | SND_JACK_BTN_0;
802 } else if (jack_data->intr_id & 0x2) {
803 pr_debug("long_push detected\n");
804 status = SND_JACK_HEADSET | SND_JACK_BTN_1;
805 } else if (jack_data->intr_id & 0x4) {
806 pr_debug("headset or headphones inserted\n");
807 status = sn95031_get_headset_state(jack_data->mfld_jack);
808 } else if (jack_data->intr_id & 0x8) {
809 pr_debug("headset or headphones removed\n");
810 status = 0;
811 sn95031_disable_jack_btn(jack_data->mfld_jack->codec);
812 } else {
813 pr_err("unidentified interrupt\n");
814 return;
815 }
816
817 snd_soc_jack_report(jack_data->mfld_jack, status, mask);
818 /*button pressed and released so we send explicit button release */
819 if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
820 snd_soc_jack_report(jack_data->mfld_jack,
821 SND_JACK_HEADSET, mask);
822}
823EXPORT_SYMBOL_GPL(sn95031_jack_detection);
824
652/* codec registration */ 825/* codec registration */
653static int sn95031_codec_probe(struct snd_soc_codec *codec) 826static int sn95031_codec_probe(struct snd_soc_codec *codec)
654{ 827{
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
index e2b17d908aeb..20376d234fb8 100644
--- a/sound/soc/codecs/sn95031.h
+++ b/sound/soc/codecs/sn95031.h
@@ -96,4 +96,37 @@
96#define SN95031_SSR5 0x384 96#define SN95031_SSR5 0x384
97#define SN95031_SSR6 0x385 97#define SN95031_SSR6 0x385
98 98
99/* ADC registers */
100
101#define SN95031_ADC1CNTL1 0x1C0
102#define SN95031_ADC_ENBL 0x10
103#define SN95031_ADC_START 0x08
104#define SN95031_ADC1CNTL3 0x1C2
105#define SN95031_ADCTHERM_ENBL 0x04
106#define SN95031_ADCRRDATA_ENBL 0x05
107#define SN95031_STOPBIT_MASK 16
108#define SN95031_ADCTHERM_MASK 4
109#define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */
110#define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1)
111#define SN95031_ADC_NO_LOOP 0x07
112#define SN95031_AUDIO_GPIO_CTRL 0x070
113
114/* ADC channel code values */
115#define SN95031_AUDIO_DETECT_CODE 0x06
116
117/* ADC base addresses */
118#define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
119#define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
120/* multipier to convert to mV */
121#define SN95031_ADC_ONE_LSB_MULTIPLIER 2346
122
123
124struct mfld_jack_data {
125 int intr_id;
126 int micbias_vol;
127 struct snd_soc_jack *mfld_jack;
128};
129
130extern void sn95031_jack_detection(struct mfld_jack_data *jack_data);
131
99#endif 132#endif
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
new file mode 100644
index 000000000000..e93b9d1ae1dd
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -0,0 +1,794 @@
1/*
2 * linux/sound/soc/codecs/tlv320aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02110-1301, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/pm.h>
31#include <linux/i2c.h>
32#include <linux/platform_device.h>
33#include <linux/cdev.h>
34#include <linux/slab.h>
35
36#include <sound/tlv320aic32x4.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/soc.h>
41#include <sound/soc-dapm.h>
42#include <sound/initval.h>
43#include <sound/tlv.h>
44
45#include "tlv320aic32x4.h"
46
47struct aic32x4_rate_divs {
48 u32 mclk;
49 u32 rate;
50 u8 p_val;
51 u8 pll_j;
52 u16 pll_d;
53 u16 dosr;
54 u8 ndac;
55 u8 mdac;
56 u8 aosr;
57 u8 nadc;
58 u8 madc;
59 u8 blck_N;
60};
61
62struct aic32x4_priv {
63 u32 sysclk;
64 s32 master;
65 u8 page_no;
66 void *control_data;
67 u32 power_cfg;
68 u32 micpga_routing;
69 bool swapdacs;
70};
71
72/* 0dB min, 1dB steps */
73static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0);
74/* 0dB min, 0.5dB steps */
75static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
76
77static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
78 SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
79 AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5),
80 SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
81 AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1),
82 SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
83 AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1),
84 SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
85 AIC32X4_HPRGAIN, 6, 0x01, 1),
86 SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
87 AIC32X4_LORGAIN, 6, 0x01, 1),
88 SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL,
89 AIC32X4_RMICPGAVOL, 7, 0x01, 1),
90
91 SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
92 SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
93
94 SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL,
95 AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5),
96 SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
97 AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
98
99 SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),
100
101 SOC_SINGLE("AGC Left Switch", AIC32X4_LAGC1, 7, 1, 0),
102 SOC_SINGLE("AGC Right Switch", AIC32X4_RAGC1, 7, 1, 0),
103 SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
104 4, 0x07, 0),
105 SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
106 0, 0x03, 0),
107 SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
108 6, 0x03, 0),
109 SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
110 1, 0x1F, 0),
111 SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
112 0, 0x7F, 0),
113 SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
114 3, 0x1F, 0),
115 SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
116 3, 0x1F, 0),
117 SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
118 0, 0x1F, 0),
119 SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
120 0, 0x0F, 0),
121};
122
123static const struct aic32x4_rate_divs aic32x4_divs[] = {
124 /* 8k rate */
125 {AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
126 {AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
127 {AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
128 /* 11.025k rate */
129 {AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
130 {AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
131 /* 16k rate */
132 {AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
133 {AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
134 {AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
135 /* 22.05k rate */
136 {AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
137 {AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
138 {AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
139 /* 32k rate */
140 {AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
141 {AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
142 /* 44.1k rate */
143 {AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
144 {AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
145 {AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
146 /* 48k rate */
147 {AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
148 {AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
149 {AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}
150};
151
152static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
153 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
154 SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0),
155};
156
157static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
158 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_HPRROUTE, 3, 1, 0),
159 SOC_DAPM_SINGLE("IN1_R Switch", AIC32X4_HPRROUTE, 2, 1, 0),
160};
161
162static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
163 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_LOLROUTE, 3, 1, 0),
164};
165
166static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
167 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_LORROUTE, 3, 1, 0),
168};
169
170static const struct snd_kcontrol_new left_input_mixer_controls[] = {
171 SOC_DAPM_SINGLE("IN1_L P Switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
172 SOC_DAPM_SINGLE("IN2_L P Switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
173 SOC_DAPM_SINGLE("IN3_L P Switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
174};
175
176static const struct snd_kcontrol_new right_input_mixer_controls[] = {
177 SOC_DAPM_SINGLE("IN1_R P Switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
178 SOC_DAPM_SINGLE("IN2_R P Switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
179 SOC_DAPM_SINGLE("IN3_R P Switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
180};
181
182static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
183 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
184 SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
185 &hpl_output_mixer_controls[0],
186 ARRAY_SIZE(hpl_output_mixer_controls)),
187 SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
188
189 SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
190 &lol_output_mixer_controls[0],
191 ARRAY_SIZE(lol_output_mixer_controls)),
192 SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
193
194 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
195 SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
196 &hpr_output_mixer_controls[0],
197 ARRAY_SIZE(hpr_output_mixer_controls)),
198 SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
199 SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
200 &lor_output_mixer_controls[0],
201 ARRAY_SIZE(lor_output_mixer_controls)),
202 SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
203 SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
204 &left_input_mixer_controls[0],
205 ARRAY_SIZE(left_input_mixer_controls)),
206 SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
207 &right_input_mixer_controls[0],
208 ARRAY_SIZE(right_input_mixer_controls)),
209 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
210 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
211 SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),
212
213 SND_SOC_DAPM_OUTPUT("HPL"),
214 SND_SOC_DAPM_OUTPUT("HPR"),
215 SND_SOC_DAPM_OUTPUT("LOL"),
216 SND_SOC_DAPM_OUTPUT("LOR"),
217 SND_SOC_DAPM_INPUT("IN1_L"),
218 SND_SOC_DAPM_INPUT("IN1_R"),
219 SND_SOC_DAPM_INPUT("IN2_L"),
220 SND_SOC_DAPM_INPUT("IN2_R"),
221 SND_SOC_DAPM_INPUT("IN3_L"),
222 SND_SOC_DAPM_INPUT("IN3_R"),
223};
224
225static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
226 /* Left Output */
227 {"HPL Output Mixer", "L_DAC Switch", "Left DAC"},
228 {"HPL Output Mixer", "IN1_L Switch", "IN1_L"},
229
230 {"HPL Power", NULL, "HPL Output Mixer"},
231 {"HPL", NULL, "HPL Power"},
232
233 {"LOL Output Mixer", "L_DAC Switch", "Left DAC"},
234
235 {"LOL Power", NULL, "LOL Output Mixer"},
236 {"LOL", NULL, "LOL Power"},
237
238 /* Right Output */
239 {"HPR Output Mixer", "R_DAC Switch", "Right DAC"},
240 {"HPR Output Mixer", "IN1_R Switch", "IN1_R"},
241
242 {"HPR Power", NULL, "HPR Output Mixer"},
243 {"HPR", NULL, "HPR Power"},
244
245 {"LOR Output Mixer", "R_DAC Switch", "Right DAC"},
246
247 {"LOR Power", NULL, "LOR Output Mixer"},
248 {"LOR", NULL, "LOR Power"},
249
250 /* Left input */
251 {"Left Input Mixer", "IN1_L P Switch", "IN1_L"},
252 {"Left Input Mixer", "IN2_L P Switch", "IN2_L"},
253 {"Left Input Mixer", "IN3_L P Switch", "IN3_L"},
254
255 {"Left ADC", NULL, "Left Input Mixer"},
256
257 /* Right Input */
258 {"Right Input Mixer", "IN1_R P Switch", "IN1_R"},
259 {"Right Input Mixer", "IN2_R P Switch", "IN2_R"},
260 {"Right Input Mixer", "IN3_R P Switch", "IN3_R"},
261
262 {"Right ADC", NULL, "Right Input Mixer"},
263};
264
265static inline int aic32x4_change_page(struct snd_soc_codec *codec,
266 unsigned int new_page)
267{
268 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
269 u8 data[2];
270 int ret;
271
272 data[0] = 0x00;
273 data[1] = new_page & 0xff;
274
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret == 2) {
277 aic32x4->page_no = new_page;
278 return 0;
279 } else {
280 return ret;
281 }
282}
283
284static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg,
285 unsigned int val)
286{
287 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
288 unsigned int page = reg / 128;
289 unsigned int fixed_reg = reg % 128;
290 u8 data[2];
291 int ret;
292
293 /* A write to AIC32X4_PSEL is really a non-explicit page change */
294 if (reg == AIC32X4_PSEL)
295 return aic32x4_change_page(codec, val);
296
297 if (aic32x4->page_no != page) {
298 ret = aic32x4_change_page(codec, page);
299 if (ret != 0)
300 return ret;
301 }
302
303 data[0] = fixed_reg & 0xff;
304 data[1] = val & 0xff;
305
306 if (codec->hw_write(codec->control_data, data, 2) == 2)
307 return 0;
308 else
309 return -EIO;
310}
311
312static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg)
313{
314 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
315 unsigned int page = reg / 128;
316 unsigned int fixed_reg = reg % 128;
317 int ret;
318
319 if (aic32x4->page_no != page) {
320 ret = aic32x4_change_page(codec, page);
321 if (ret != 0)
322 return ret;
323 }
324 return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff);
325}
326
327static inline int aic32x4_get_divs(int mclk, int rate)
328{
329 int i;
330
331 for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
332 if ((aic32x4_divs[i].rate == rate)
333 && (aic32x4_divs[i].mclk == mclk)) {
334 return i;
335 }
336 }
337 printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
338 return -EINVAL;
339}
340
341static int aic32x4_add_widgets(struct snd_soc_codec *codec)
342{
343 snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
344 ARRAY_SIZE(aic32x4_dapm_widgets));
345
346 snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
347 ARRAY_SIZE(aic32x4_dapm_routes));
348
349 snd_soc_dapm_new_widgets(&codec->dapm);
350 return 0;
351}
352
353static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir)
355{
356 struct snd_soc_codec *codec = codec_dai->codec;
357 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
358
359 switch (freq) {
360 case AIC32X4_FREQ_12000000:
361 case AIC32X4_FREQ_24000000:
362 case AIC32X4_FREQ_25000000:
363 aic32x4->sysclk = freq;
364 return 0;
365 }
366 printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
367 return -EINVAL;
368}
369
370static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
371{
372 struct snd_soc_codec *codec = codec_dai->codec;
373 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
374 u8 iface_reg_1;
375 u8 iface_reg_2;
376 u8 iface_reg_3;
377
378 iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
379 iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
380 iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
381 iface_reg_2 = 0;
382 iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
383 iface_reg_3 = iface_reg_3 & ~(1 << 3);
384
385 /* set master/slave audio interface */
386 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
387 case SND_SOC_DAIFMT_CBM_CFM:
388 aic32x4->master = 1;
389 iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 aic32x4->master = 0;
393 break;
394 default:
395 printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
396 return -EINVAL;
397 }
398
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 break;
402 case SND_SOC_DAIFMT_DSP_A:
403 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
404 iface_reg_3 |= (1 << 3); /* invert bit clock */
405 iface_reg_2 = 0x01; /* add offset 1 */
406 break;
407 case SND_SOC_DAIFMT_DSP_B:
408 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
409 iface_reg_3 |= (1 << 3); /* invert bit clock */
410 break;
411 case SND_SOC_DAIFMT_RIGHT_J:
412 iface_reg_1 |=
413 (AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
414 break;
415 case SND_SOC_DAIFMT_LEFT_J:
416 iface_reg_1 |=
417 (AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
418 break;
419 default:
420 printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
421 return -EINVAL;
422 }
423
424 snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
425 snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
426 snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);
427 return 0;
428}
429
430static int aic32x4_hw_params(struct snd_pcm_substream *substream,
431 struct snd_pcm_hw_params *params,
432 struct snd_soc_dai *dai)
433{
434 struct snd_soc_codec *codec = dai->codec;
435 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
436 u8 data;
437 int i;
438
439 i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
440 if (i < 0) {
441 printk(KERN_ERR "aic32x4: sampling rate not supported\n");
442 return i;
443 }
444
445 /* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
446 snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
447 snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);
448
449 /* We will fix R value to 1 and will make P & J=K.D as varialble */
450 data = snd_soc_read(codec, AIC32X4_PLLPR);
451 data &= ~(7 << 4);
452 snd_soc_write(codec, AIC32X4_PLLPR,
453 (data | (aic32x4_divs[i].p_val << 4) | 0x01));
454
455 snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
456
457 snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
458 snd_soc_write(codec, AIC32X4_PLLDLSB,
459 (aic32x4_divs[i].pll_d & 0xff));
460
461 /* NDAC divider value */
462 data = snd_soc_read(codec, AIC32X4_NDAC);
463 data &= ~(0x7f);
464 snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
465
466 /* MDAC divider value */
467 data = snd_soc_read(codec, AIC32X4_MDAC);
468 data &= ~(0x7f);
469 snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
470
471 /* DOSR MSB & LSB values */
472 snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
473 snd_soc_write(codec, AIC32X4_DOSRLSB,
474 (aic32x4_divs[i].dosr & 0xff));
475
476 /* NADC divider value */
477 data = snd_soc_read(codec, AIC32X4_NADC);
478 data &= ~(0x7f);
479 snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
480
481 /* MADC divider value */
482 data = snd_soc_read(codec, AIC32X4_MADC);
483 data &= ~(0x7f);
484 snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
485
486 /* AOSR value */
487 snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
488
489 /* BCLK N divider */
490 data = snd_soc_read(codec, AIC32X4_BCLKN);
491 data &= ~(0x7f);
492 snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
493
494 data = snd_soc_read(codec, AIC32X4_IFACE1);
495 data = data & ~(3 << 4);
496 switch (params_format(params)) {
497 case SNDRV_PCM_FORMAT_S16_LE:
498 break;
499 case SNDRV_PCM_FORMAT_S20_3LE:
500 data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
501 break;
502 case SNDRV_PCM_FORMAT_S24_LE:
503 data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
504 break;
505 case SNDRV_PCM_FORMAT_S32_LE:
506 data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
507 break;
508 }
509 snd_soc_write(codec, AIC32X4_IFACE1, data);
510
511 return 0;
512}
513
514static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
515{
516 struct snd_soc_codec *codec = dai->codec;
517 u8 dac_reg;
518
519 dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
520 if (mute)
521 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
522 else
523 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
524 return 0;
525}
526
527static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
528 enum snd_soc_bias_level level)
529{
530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
531 u8 value;
532
533 switch (level) {
534 case SND_SOC_BIAS_ON:
535 if (aic32x4->master) {
536 /* Switch on PLL */
537 value = snd_soc_read(codec, AIC32X4_PLLPR);
538 snd_soc_write(codec, AIC32X4_PLLPR,
539 (value | AIC32X4_PLLEN));
540
541 /* Switch on NDAC Divider */
542 value = snd_soc_read(codec, AIC32X4_NDAC);
543 snd_soc_write(codec, AIC32X4_NDAC,
544 value | AIC32X4_NDACEN);
545
546 /* Switch on MDAC Divider */
547 value = snd_soc_read(codec, AIC32X4_MDAC);
548 snd_soc_write(codec, AIC32X4_MDAC,
549 value | AIC32X4_MDACEN);
550
551 /* Switch on NADC Divider */
552 value = snd_soc_read(codec, AIC32X4_NADC);
553 snd_soc_write(codec, AIC32X4_NADC,
554 value | AIC32X4_MDACEN);
555
556 /* Switch on MADC Divider */
557 value = snd_soc_read(codec, AIC32X4_MADC);
558 snd_soc_write(codec, AIC32X4_MADC,
559 value | AIC32X4_MDACEN);
560
561 /* Switch on BCLK_N Divider */
562 value = snd_soc_read(codec, AIC32X4_BCLKN);
563 snd_soc_write(codec, AIC32X4_BCLKN,
564 value | AIC32X4_BCLKEN);
565 }
566 break;
567 case SND_SOC_BIAS_PREPARE:
568 break;
569 case SND_SOC_BIAS_STANDBY:
570 if (aic32x4->master) {
571 /* Switch off PLL */
572 value = snd_soc_read(codec, AIC32X4_PLLPR);
573 snd_soc_write(codec, AIC32X4_PLLPR,
574 (value & ~AIC32X4_PLLEN));
575
576 /* Switch off NDAC Divider */
577 value = snd_soc_read(codec, AIC32X4_NDAC);
578 snd_soc_write(codec, AIC32X4_NDAC,
579 value & ~AIC32X4_NDACEN);
580
581 /* Switch off MDAC Divider */
582 value = snd_soc_read(codec, AIC32X4_MDAC);
583 snd_soc_write(codec, AIC32X4_MDAC,
584 value & ~AIC32X4_MDACEN);
585
586 /* Switch off NADC Divider */
587 value = snd_soc_read(codec, AIC32X4_NADC);
588 snd_soc_write(codec, AIC32X4_NADC,
589 value & ~AIC32X4_NDACEN);
590
591 /* Switch off MADC Divider */
592 value = snd_soc_read(codec, AIC32X4_MADC);
593 snd_soc_write(codec, AIC32X4_MADC,
594 value & ~AIC32X4_MDACEN);
595 value = snd_soc_read(codec, AIC32X4_BCLKN);
596
597 /* Switch off BCLK_N Divider */
598 snd_soc_write(codec, AIC32X4_BCLKN,
599 value & ~AIC32X4_BCLKEN);
600 }
601 break;
602 case SND_SOC_BIAS_OFF:
603 break;
604 }
605 codec->dapm.bias_level = level;
606 return 0;
607}
608
609#define AIC32X4_RATES SNDRV_PCM_RATE_8000_48000
610#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
611 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
612
613static struct snd_soc_dai_ops aic32x4_ops = {
614 .hw_params = aic32x4_hw_params,
615 .digital_mute = aic32x4_mute,
616 .set_fmt = aic32x4_set_dai_fmt,
617 .set_sysclk = aic32x4_set_dai_sysclk,
618};
619
620static struct snd_soc_dai_driver aic32x4_dai = {
621 .name = "tlv320aic32x4-hifi",
622 .playback = {
623 .stream_name = "Playback",
624 .channels_min = 1,
625 .channels_max = 2,
626 .rates = AIC32X4_RATES,
627 .formats = AIC32X4_FORMATS,},
628 .capture = {
629 .stream_name = "Capture",
630 .channels_min = 1,
631 .channels_max = 2,
632 .rates = AIC32X4_RATES,
633 .formats = AIC32X4_FORMATS,},
634 .ops = &aic32x4_ops,
635 .symmetric_rates = 1,
636};
637
638static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state)
639{
640 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
641 return 0;
642}
643
644static int aic32x4_resume(struct snd_soc_codec *codec)
645{
646 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
647 return 0;
648}
649
650static int aic32x4_probe(struct snd_soc_codec *codec)
651{
652 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
653 u32 tmp_reg;
654
655 codec->hw_write = (hw_write_t) i2c_master_send;
656 codec->control_data = aic32x4->control_data;
657
658 snd_soc_write(codec, AIC32X4_RESET, 0x01);
659
660 /* Power platform configuration */
661 if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
662 snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
663 AIC32X4_MICBIAS_2075V);
664 }
665 if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
666 snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
667 }
668 if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) {
669 snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN);
670 }
671 tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
672 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
673 tmp_reg |= AIC32X4_LDOIN_18_36;
674 }
675 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) {
676 tmp_reg |= AIC32X4_LDOIN2HP;
677 }
678 snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
679
680 /* Do DACs need to be swapped? */
681 if (aic32x4->swapdacs) {
682 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2RCHN | AIC32X4_RDAC2LCHN);
683 } else {
684 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN);
685 }
686
687 /* Mic PGA routing */
688 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
689 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
690 }
691 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
692 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
693 }
694
695 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
696 snd_soc_add_controls(codec, aic32x4_snd_controls,
697 ARRAY_SIZE(aic32x4_snd_controls));
698 aic32x4_add_widgets(codec);
699
700 return 0;
701}
702
703static int aic32x4_remove(struct snd_soc_codec *codec)
704{
705 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
706 return 0;
707}
708
709static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
710 .read = aic32x4_read,
711 .write = aic32x4_write,
712 .probe = aic32x4_probe,
713 .remove = aic32x4_remove,
714 .suspend = aic32x4_suspend,
715 .resume = aic32x4_resume,
716 .set_bias_level = aic32x4_set_bias_level,
717};
718
719static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
720 const struct i2c_device_id *id)
721{
722 struct aic32x4_pdata *pdata = i2c->dev.platform_data;
723 struct aic32x4_priv *aic32x4;
724 int ret;
725
726 aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL);
727 if (aic32x4 == NULL)
728 return -ENOMEM;
729
730 aic32x4->control_data = i2c;
731 i2c_set_clientdata(i2c, aic32x4);
732
733 if (pdata) {
734 aic32x4->power_cfg = pdata->power_cfg;
735 aic32x4->swapdacs = pdata->swapdacs;
736 aic32x4->micpga_routing = pdata->micpga_routing;
737 } else {
738 aic32x4->power_cfg = 0;
739 aic32x4->swapdacs = false;
740 aic32x4->micpga_routing = 0;
741 }
742
743 ret = snd_soc_register_codec(&i2c->dev,
744 &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
745 if (ret < 0)
746 kfree(aic32x4);
747 return ret;
748}
749
750static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
751{
752 snd_soc_unregister_codec(&client->dev);
753 kfree(i2c_get_clientdata(client));
754 return 0;
755}
756
757static const struct i2c_device_id aic32x4_i2c_id[] = {
758 { "tlv320aic32x4", 0 },
759 { }
760};
761MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
762
763static struct i2c_driver aic32x4_i2c_driver = {
764 .driver = {
765 .name = "tlv320aic32x4",
766 .owner = THIS_MODULE,
767 },
768 .probe = aic32x4_i2c_probe,
769 .remove = __devexit_p(aic32x4_i2c_remove),
770 .id_table = aic32x4_i2c_id,
771};
772
773static int __init aic32x4_modinit(void)
774{
775 int ret = 0;
776
777 ret = i2c_add_driver(&aic32x4_i2c_driver);
778 if (ret != 0) {
779 printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
780 ret);
781 }
782 return ret;
783}
784module_init(aic32x4_modinit);
785
786static void __exit aic32x4_exit(void)
787{
788 i2c_del_driver(&aic32x4_i2c_driver);
789}
790module_exit(aic32x4_exit);
791
792MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
793MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
794MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h
new file mode 100644
index 000000000000..aae2b2440398
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.h
@@ -0,0 +1,143 @@
1/*
2 * tlv320aic32x4.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9
10#ifndef _TLV320AIC32X4_H
11#define _TLV320AIC32X4_H
12
13/* tlv320aic32x4 register space (in decimal to match datasheet) */
14
15#define AIC32X4_PAGE1 128
16
17#define AIC32X4_PSEL 0
18#define AIC32X4_RESET 1
19#define AIC32X4_CLKMUX 4
20#define AIC32X4_PLLPR 5
21#define AIC32X4_PLLJ 6
22#define AIC32X4_PLLDMSB 7
23#define AIC32X4_PLLDLSB 8
24#define AIC32X4_NDAC 11
25#define AIC32X4_MDAC 12
26#define AIC32X4_DOSRMSB 13
27#define AIC32X4_DOSRLSB 14
28#define AIC32X4_NADC 18
29#define AIC32X4_MADC 19
30#define AIC32X4_AOSR 20
31#define AIC32X4_CLKMUX2 25
32#define AIC32X4_CLKOUTM 26
33#define AIC32X4_IFACE1 27
34#define AIC32X4_IFACE2 28
35#define AIC32X4_IFACE3 29
36#define AIC32X4_BCLKN 30
37#define AIC32X4_IFACE4 31
38#define AIC32X4_IFACE5 32
39#define AIC32X4_IFACE6 33
40#define AIC32X4_DOUTCTL 53
41#define AIC32X4_DINCTL 54
42#define AIC32X4_DACSPB 60
43#define AIC32X4_ADCSPB 61
44#define AIC32X4_DACSETUP 63
45#define AIC32X4_DACMUTE 64
46#define AIC32X4_LDACVOL 65
47#define AIC32X4_RDACVOL 66
48#define AIC32X4_ADCSETUP 81
49#define AIC32X4_ADCFGA 82
50#define AIC32X4_LADCVOL 83
51#define AIC32X4_RADCVOL 84
52#define AIC32X4_LAGC1 86
53#define AIC32X4_LAGC2 87
54#define AIC32X4_LAGC3 88
55#define AIC32X4_LAGC4 89
56#define AIC32X4_LAGC5 90
57#define AIC32X4_LAGC6 91
58#define AIC32X4_LAGC7 92
59#define AIC32X4_RAGC1 94
60#define AIC32X4_RAGC2 95
61#define AIC32X4_RAGC3 96
62#define AIC32X4_RAGC4 97
63#define AIC32X4_RAGC5 98
64#define AIC32X4_RAGC6 99
65#define AIC32X4_RAGC7 100
66#define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1)
67#define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2)
68#define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9)
69#define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10)
70#define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12)
71#define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13)
72#define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14)
73#define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15)
74#define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16)
75#define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17)
76#define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18)
77#define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19)
78#define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20)
79#define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51)
80#define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52)
81#define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54)
82#define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55)
83#define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57)
84#define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58)
85#define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59)
86#define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60)
87
88#define AIC32X4_FREQ_12000000 12000000
89#define AIC32X4_FREQ_24000000 24000000
90#define AIC32X4_FREQ_25000000 25000000
91
92#define AIC32X4_WORD_LEN_16BITS 0x00
93#define AIC32X4_WORD_LEN_20BITS 0x01
94#define AIC32X4_WORD_LEN_24BITS 0x02
95#define AIC32X4_WORD_LEN_32BITS 0x03
96
97#define AIC32X4_I2S_MODE 0x00
98#define AIC32X4_DSP_MODE 0x01
99#define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02
100#define AIC32X4_LEFT_JUSTIFIED_MODE 0x03
101
102#define AIC32X4_AVDDWEAKDISABLE 0x08
103#define AIC32X4_LDOCTLEN 0x01
104
105#define AIC32X4_LDOIN_18_36 0x01
106#define AIC32X4_LDOIN2HP 0x02
107
108#define AIC32X4_DACSPBLOCK_MASK 0x1f
109#define AIC32X4_ADCSPBLOCK_MASK 0x1f
110
111#define AIC32X4_PLLJ_SHIFT 6
112#define AIC32X4_DOSRMSB_SHIFT 4
113
114#define AIC32X4_PLLCLKIN 0x03
115
116#define AIC32X4_MICBIAS_LDOIN 0x08
117#define AIC32X4_MICBIAS_2075V 0x60
118
119#define AIC32X4_LMICPGANIN_IN2R_10K 0x10
120#define AIC32X4_RMICPGANIN_IN1L_10K 0x10
121
122#define AIC32X4_LMICPGAVOL_NOGAIN 0x80
123#define AIC32X4_RMICPGAVOL_NOGAIN 0x80
124
125#define AIC32X4_BCLKMASTER 0x08
126#define AIC32X4_WCLKMASTER 0x04
127#define AIC32X4_PLLEN (0x01 << 7)
128#define AIC32X4_NDACEN (0x01 << 7)
129#define AIC32X4_MDACEN (0x01 << 7)
130#define AIC32X4_NADCEN (0x01 << 7)
131#define AIC32X4_MADCEN (0x01 << 7)
132#define AIC32X4_BCLKEN (0x01 << 7)
133#define AIC32X4_DACEN (0x03 << 6)
134#define AIC32X4_RDAC2LCHN (0x02 << 2)
135#define AIC32X4_LDAC2RCHN (0x02 << 4)
136#define AIC32X4_LDAC2LCHN (0x01 << 4)
137#define AIC32X4_RDAC2RCHN (0x01 << 2)
138
139#define AIC32X4_SSTEP2WCLK 0x01
140#define AIC32X4_MUTEON 0x0C
141#define AIC32X4_DACMOD2BCLK 0x01
142
143#endif /* _TLV320AIC32X4_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 71d7be8ac488..00b6d87e7bdb 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1615,6 +1615,7 @@ static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1615 }, 1615 },
1616 { }, 1616 { },
1617}; 1617};
1618MODULE_DEVICE_TABLE(i2c, tlv320dac33_i2c_id);
1618 1619
1619static struct i2c_driver tlv320dac33_i2c_driver = { 1620static struct i2c_driver tlv320dac33_i2c_driver = {
1620 .driver = { 1621 .driver = {
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 80ddf4fd23db..a3b9cbb20ee9 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -836,24 +836,25 @@ static void wm2000_i2c_shutdown(struct i2c_client *i2c)
836} 836}
837 837
838#ifdef CONFIG_PM 838#ifdef CONFIG_PM
839static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) 839static int wm2000_i2c_suspend(struct device *dev)
840{ 840{
841 struct i2c_client *i2c = to_i2c_client(dev);
841 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 842 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
842 843
843 return wm2000_anc_transition(wm2000, ANC_OFF); 844 return wm2000_anc_transition(wm2000, ANC_OFF);
844} 845}
845 846
846static int wm2000_i2c_resume(struct i2c_client *i2c) 847static int wm2000_i2c_resume(struct device *dev)
847{ 848{
849 struct i2c_client *i2c = to_i2c_client(dev);
848 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 850 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
849 851
850 return wm2000_anc_set_mode(wm2000); 852 return wm2000_anc_set_mode(wm2000);
851} 853}
852#else
853#define wm2000_i2c_suspend NULL
854#define wm2000_i2c_resume NULL
855#endif 854#endif
856 855
856static SIMPLE_DEV_PM_OPS(wm2000_pm, wm2000_i2c_suspend, wm2000_i2c_resume);
857
857static const struct i2c_device_id wm2000_i2c_id[] = { 858static const struct i2c_device_id wm2000_i2c_id[] = {
858 { "wm2000", 0 }, 859 { "wm2000", 0 },
859 { } 860 { }
@@ -864,11 +865,10 @@ static struct i2c_driver wm2000_i2c_driver = {
864 .driver = { 865 .driver = {
865 .name = "wm2000", 866 .name = "wm2000",
866 .owner = THIS_MODULE, 867 .owner = THIS_MODULE,
868 .pm = &wm2000_pm,
867 }, 869 },
868 .probe = wm2000_i2c_probe, 870 .probe = wm2000_i2c_probe,
869 .remove = __devexit_p(wm2000_i2c_remove), 871 .remove = __devexit_p(wm2000_i2c_remove),
870 .suspend = wm2000_i2c_suspend,
871 .resume = wm2000_i2c_resume,
872 .shutdown = wm2000_i2c_shutdown, 872 .shutdown = wm2000_i2c_shutdown,
873 .id_table = wm2000_i2c_id, 873 .id_table = wm2000_i2c_id,
874}; 874};
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 79b02ae125c5..3f09deea8d9d 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -55,8 +55,10 @@ static int caps_charge = 2000;
55module_param(caps_charge, int, 0); 55module_param(caps_charge, int, 0);
56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
57 57
58static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 58static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
59 struct snd_soc_dai *dai, unsigned int hifi); 59 unsigned int fmt);
60static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
61 unsigned int fmt);
60 62
61/* 63/*
62 * wm8753 register cache 64 * wm8753 register cache
@@ -87,6 +89,10 @@ struct wm8753_priv {
87 enum snd_soc_control_type control_type; 89 enum snd_soc_control_type control_type;
88 unsigned int sysclk; 90 unsigned int sysclk;
89 unsigned int pcmclk; 91 unsigned int pcmclk;
92
93 unsigned int voice_fmt;
94 unsigned int hifi_fmt;
95
90 int dai_func; 96 int dai_func;
91}; 97};
92 98
@@ -170,9 +176,9 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
170 struct snd_ctl_elem_value *ucontrol) 176 struct snd_ctl_elem_value *ucontrol)
171{ 177{
172 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 178 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
173 int mode = snd_soc_read(codec, WM8753_IOCTL); 179 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
174 180
175 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; 181 ucontrol->value.integer.value[0] = wm8753->dai_func;
176 return 0; 182 return 0;
177} 183}
178 184
@@ -180,16 +186,26 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol) 186 struct snd_ctl_elem_value *ucontrol)
181{ 187{
182 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 188 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
183 int mode = snd_soc_read(codec, WM8753_IOCTL);
184 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 189 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
190 u16 ioctl;
191
192 if (codec->active)
193 return -EBUSY;
194
195 ioctl = snd_soc_read(codec, WM8753_IOCTL);
196
197 wm8753->dai_func = ucontrol->value.integer.value[0];
198
199 if (((ioctl >> 2) & 0x3) == wm8753->dai_func)
200 return 1;
201
202 ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
203 snd_soc_write(codec, WM8753_IOCTL, ioctl);
185 204
186 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
187 return 0;
188 205
189 mode &= 0xfff3; 206 wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
190 mode |= (ucontrol->value.integer.value[0] << 2); 207 wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
191 208
192 wm8753->dai_func = ucontrol->value.integer.value[0];
193 return 1; 209 return 1;
194} 210}
195 211
@@ -828,10 +844,9 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
828/* 844/*
829 * Set's ADC and Voice DAC format. 845 * Set's ADC and Voice DAC format.
830 */ 846 */
831static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, 847static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
832 unsigned int fmt) 848 unsigned int fmt)
833{ 849{
834 struct snd_soc_codec *codec = codec_dai->codec;
835 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec; 850 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
836 851
837 /* interface format */ 852 /* interface format */
@@ -858,13 +873,6 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
858 return 0; 873 return 0;
859} 874}
860 875
861static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
862 struct snd_soc_dai *dai)
863{
864 wm8753_set_dai_mode(dai->codec, dai, 0);
865 return 0;
866}
867
868/* 876/*
869 * Set PCM DAI bit size and sample rate. 877 * Set PCM DAI bit size and sample rate.
870 */ 878 */
@@ -905,10 +913,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
905/* 913/*
906 * Set's PCM dai fmt and BCLK. 914 * Set's PCM dai fmt and BCLK.
907 */ 915 */
908static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, 916static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
909 unsigned int fmt) 917 unsigned int fmt)
910{ 918{
911 struct snd_soc_codec *codec = codec_dai->codec;
912 u16 voice, ioctl; 919 u16 voice, ioctl;
913 920
914 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f; 921 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
@@ -999,10 +1006,9 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
999/* 1006/*
1000 * Set's HiFi DAC format. 1007 * Set's HiFi DAC format.
1001 */ 1008 */
1002static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, 1009static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
1003 unsigned int fmt) 1010 unsigned int fmt)
1004{ 1011{
1005 struct snd_soc_codec *codec = codec_dai->codec;
1006 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0; 1012 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
1007 1013
1008 /* interface format */ 1014 /* interface format */
@@ -1032,10 +1038,9 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1032/* 1038/*
1033 * Set's I2S DAI format. 1039 * Set's I2S DAI format.
1034 */ 1040 */
1035static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, 1041static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
1036 unsigned int fmt) 1042 unsigned int fmt)
1037{ 1043{
1038 struct snd_soc_codec *codec = codec_dai->codec;
1039 u16 ioctl, hifi; 1044 u16 ioctl, hifi;
1040 1045
1041 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f; 1046 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
@@ -1098,13 +1103,6 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1098 return 0; 1103 return 0;
1099} 1104}
1100 1105
1101static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
1102 struct snd_soc_dai *dai)
1103{
1104 wm8753_set_dai_mode(dai->codec, dai, 1);
1105 return 0;
1106}
1107
1108/* 1106/*
1109 * Set PCM DAI bit size and sample rate. 1107 * Set PCM DAI bit size and sample rate.
1110 */ 1108 */
@@ -1147,61 +1145,117 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1147 return 0; 1145 return 0;
1148} 1146}
1149 1147
1150static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, 1148static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
1151 unsigned int fmt) 1149 unsigned int fmt)
1152{ 1150{
1153 struct snd_soc_codec *codec = codec_dai->codec;
1154 u16 clock; 1151 u16 clock;
1155 1152
1156 /* set clk source as pcmclk */ 1153 /* set clk source as pcmclk */
1157 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1154 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1158 snd_soc_write(codec, WM8753_CLOCK, clock); 1155 snd_soc_write(codec, WM8753_CLOCK, clock);
1159 1156
1160 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1157 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1161 return -EINVAL;
1162 return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
1163} 1158}
1164 1159
1165static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai, 1160static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
1166 unsigned int fmt) 1161 unsigned int fmt)
1167{ 1162{
1168 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1163 return wm8753_hdac_set_dai_fmt(codec, fmt);
1169 return -EINVAL;
1170 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1171} 1164}
1172 1165
1173static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, 1166static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
1174 unsigned int fmt) 1167 unsigned int fmt)
1175{ 1168{
1176 struct snd_soc_codec *codec = codec_dai->codec;
1177 u16 clock; 1169 u16 clock;
1178 1170
1179 /* set clk source as pcmclk */ 1171 /* set clk source as pcmclk */
1180 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1172 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1181 snd_soc_write(codec, WM8753_CLOCK, clock); 1173 snd_soc_write(codec, WM8753_CLOCK, clock);
1182 1174
1183 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1175 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1184 return -EINVAL;
1185 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1186} 1176}
1187 1177
1188static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, 1178static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
1189 unsigned int fmt) 1179 unsigned int fmt)
1190{ 1180{
1191 struct snd_soc_codec *codec = codec_dai->codec;
1192 u16 clock; 1181 u16 clock;
1193 1182
1194 /* set clk source as mclk */ 1183 /* set clk source as mclk */
1195 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1184 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1196 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4); 1185 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
1197 1186
1198 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1187 if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
1199 return -EINVAL; 1188 return -EINVAL;
1200 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1189 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1201 return -EINVAL;
1202 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1203} 1190}
1204 1191
1192static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
1193 unsigned int fmt)
1194{
1195 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1196 int ret = 0;
1197
1198 switch (wm8753->dai_func) {
1199 case 0:
1200 ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
1201 break;
1202 case 1:
1203 ret = wm8753_mode2_set_dai_fmt(codec, fmt);
1204 break;
1205 case 2:
1206 case 3:
1207 ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
1208 break;
1209 default:
1210 break;
1211 }
1212 if (ret)
1213 return ret;
1214
1215 return wm8753_i2s_set_dai_fmt(codec, fmt);
1216}
1217
1218static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
1219 unsigned int fmt)
1220{
1221 struct snd_soc_codec *codec = codec_dai->codec;
1222 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1223
1224 wm8753->hifi_fmt = fmt;
1225
1226 return wm8753_hifi_write_dai_fmt(codec, fmt);
1227};
1228
1229static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
1230 unsigned int fmt)
1231{
1232 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1233 int ret = 0;
1234
1235 if (wm8753->dai_func != 0)
1236 return 0;
1237
1238 ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
1239 if (ret)
1240 return ret;
1241 ret = wm8753_pcm_set_dai_fmt(codec, fmt);
1242 if (ret)
1243 return ret;
1244
1245 return 0;
1246};
1247
1248static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1249 unsigned int fmt)
1250{
1251 struct snd_soc_codec *codec = codec_dai->codec;
1252 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1253
1254 wm8753->voice_fmt = fmt;
1255
1256 return wm8753_voice_write_dai_fmt(codec, fmt);
1257};
1258
1205static int wm8753_mute(struct snd_soc_dai *dai, int mute) 1259static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1206{ 1260{
1207 struct snd_soc_codec *codec = dai->codec; 1261 struct snd_soc_codec *codec = dai->codec;
@@ -1268,57 +1322,25 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1268 * 3. Voice disabled - HIFI over HIFI 1322 * 3. Voice disabled - HIFI over HIFI
1269 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1323 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1270 */ 1324 */
1271static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { 1325static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
1272 .startup = wm8753_i2s_startup,
1273 .hw_params = wm8753_i2s_hw_params, 1326 .hw_params = wm8753_i2s_hw_params,
1274 .digital_mute = wm8753_mute, 1327 .digital_mute = wm8753_mute,
1275 .set_fmt = wm8753_mode1h_set_dai_fmt, 1328 .set_fmt = wm8753_hifi_set_dai_fmt,
1276 .set_clkdiv = wm8753_set_dai_clkdiv,
1277 .set_pll = wm8753_set_dai_pll,
1278 .set_sysclk = wm8753_set_dai_sysclk,
1279};
1280
1281static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1282 .startup = wm8753_pcm_startup,
1283 .hw_params = wm8753_pcm_hw_params,
1284 .digital_mute = wm8753_mute,
1285 .set_fmt = wm8753_mode1v_set_dai_fmt,
1286 .set_clkdiv = wm8753_set_dai_clkdiv, 1329 .set_clkdiv = wm8753_set_dai_clkdiv,
1287 .set_pll = wm8753_set_dai_pll, 1330 .set_pll = wm8753_set_dai_pll,
1288 .set_sysclk = wm8753_set_dai_sysclk, 1331 .set_sysclk = wm8753_set_dai_sysclk,
1289}; 1332};
1290 1333
1291static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { 1334static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
1292 .startup = wm8753_pcm_startup,
1293 .hw_params = wm8753_pcm_hw_params, 1335 .hw_params = wm8753_pcm_hw_params,
1294 .digital_mute = wm8753_mute, 1336 .digital_mute = wm8753_mute,
1295 .set_fmt = wm8753_mode2_set_dai_fmt, 1337 .set_fmt = wm8753_voice_set_dai_fmt,
1296 .set_clkdiv = wm8753_set_dai_clkdiv,
1297 .set_pll = wm8753_set_dai_pll,
1298 .set_sysclk = wm8753_set_dai_sysclk,
1299};
1300
1301static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1302 .startup = wm8753_i2s_startup,
1303 .hw_params = wm8753_i2s_hw_params,
1304 .digital_mute = wm8753_mute,
1305 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1306 .set_clkdiv = wm8753_set_dai_clkdiv,
1307 .set_pll = wm8753_set_dai_pll,
1308 .set_sysclk = wm8753_set_dai_sysclk,
1309};
1310
1311static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1312 .startup = wm8753_i2s_startup,
1313 .hw_params = wm8753_i2s_hw_params,
1314 .digital_mute = wm8753_mute,
1315 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1316 .set_clkdiv = wm8753_set_dai_clkdiv, 1338 .set_clkdiv = wm8753_set_dai_clkdiv,
1317 .set_pll = wm8753_set_dai_pll, 1339 .set_pll = wm8753_set_dai_pll,
1318 .set_sysclk = wm8753_set_dai_sysclk, 1340 .set_sysclk = wm8753_set_dai_sysclk,
1319}; 1341};
1320 1342
1321static struct snd_soc_dai_driver wm8753_all_dai[] = { 1343static struct snd_soc_dai_driver wm8753_dai[] = {
1322/* DAI HiFi mode 1 */ 1344/* DAI HiFi mode 1 */
1323{ .name = "wm8753-hifi", 1345{ .name = "wm8753-hifi",
1324 .playback = { 1346 .playback = {
@@ -1326,14 +1348,16 @@ static struct snd_soc_dai_driver wm8753_all_dai[] = {
1326 .channels_min = 1, 1348 .channels_min = 1,
1327 .channels_max = 2, 1349 .channels_max = 2,
1328 .rates = WM8753_RATES, 1350 .rates = WM8753_RATES,
1329 .formats = WM8753_FORMATS}, 1351 .formats = WM8753_FORMATS
1352 },
1330 .capture = { /* dummy for fast DAI switching */ 1353 .capture = { /* dummy for fast DAI switching */
1331 .stream_name = "Capture", 1354 .stream_name = "Capture",
1332 .channels_min = 1, 1355 .channels_min = 1,
1333 .channels_max = 2, 1356 .channels_max = 2,
1334 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1335 .formats = WM8753_FORMATS}, 1358 .formats = WM8753_FORMATS
1336 .ops = &wm8753_dai_ops_hifi_mode1, 1359 },
1360 .ops = &wm8753_dai_ops_hifi_mode,
1337}, 1361},
1338/* DAI Voice mode 1 */ 1362/* DAI Voice mode 1 */
1339{ .name = "wm8753-voice", 1363{ .name = "wm8753-voice",
@@ -1342,97 +1366,19 @@ static struct snd_soc_dai_driver wm8753_all_dai[] = {
1342 .channels_min = 1, 1366 .channels_min = 1,
1343 .channels_max = 1, 1367 .channels_max = 1,
1344 .rates = WM8753_RATES, 1368 .rates = WM8753_RATES,
1345 .formats = WM8753_FORMATS,}, 1369 .formats = WM8753_FORMATS,
1346 .capture = { 1370 },
1347 .stream_name = "Capture",
1348 .channels_min = 1,
1349 .channels_max = 2,
1350 .rates = WM8753_RATES,
1351 .formats = WM8753_FORMATS,},
1352 .ops = &wm8753_dai_ops_voice_mode1,
1353},
1354/* DAI HiFi mode 2 - dummy */
1355{ .name = "wm8753-hifi",
1356},
1357/* DAI Voice mode 2 */
1358{ .name = "wm8753-voice",
1359 .playback = {
1360 .stream_name = "Voice Playback",
1361 .channels_min = 1,
1362 .channels_max = 1,
1363 .rates = WM8753_RATES,
1364 .formats = WM8753_FORMATS,},
1365 .capture = {
1366 .stream_name = "Capture",
1367 .channels_min = 1,
1368 .channels_max = 2,
1369 .rates = WM8753_RATES,
1370 .formats = WM8753_FORMATS,},
1371 .ops = &wm8753_dai_ops_voice_mode2,
1372},
1373/* DAI HiFi mode 3 */
1374{ .name = "wm8753-hifi",
1375 .playback = {
1376 .stream_name = "HiFi Playback",
1377 .channels_min = 1,
1378 .channels_max = 2,
1379 .rates = WM8753_RATES,
1380 .formats = WM8753_FORMATS,},
1381 .capture = {
1382 .stream_name = "Capture",
1383 .channels_min = 1,
1384 .channels_max = 2,
1385 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,},
1387 .ops = &wm8753_dai_ops_hifi_mode3,
1388},
1389/* DAI Voice mode 3 - dummy */
1390{ .name = "wm8753-voice",
1391},
1392/* DAI HiFi mode 4 */
1393{ .name = "wm8753-hifi",
1394 .playback = {
1395 .stream_name = "HiFi Playback",
1396 .channels_min = 1,
1397 .channels_max = 2,
1398 .rates = WM8753_RATES,
1399 .formats = WM8753_FORMATS,},
1400 .capture = { 1371 .capture = {
1401 .stream_name = "Capture", 1372 .stream_name = "Capture",
1402 .channels_min = 1, 1373 .channels_min = 1,
1403 .channels_max = 2, 1374 .channels_max = 2,
1404 .rates = WM8753_RATES, 1375 .rates = WM8753_RATES,
1405 .formats = WM8753_FORMATS,}, 1376 .formats = WM8753_FORMATS,
1406 .ops = &wm8753_dai_ops_hifi_mode4,
1407},
1408/* DAI Voice mode 4 - dummy */
1409{ .name = "wm8753-voice",
1410},
1411};
1412
1413static struct snd_soc_dai_driver wm8753_dai[] = {
1414 {
1415 .name = "wm8753-aif0",
1416 },
1417 {
1418 .name = "wm8753-aif1",
1419 }, 1377 },
1378 .ops = &wm8753_dai_ops_voice_mode,
1379},
1420}; 1380};
1421 1381
1422static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1423 struct snd_soc_dai *dai, unsigned int hifi)
1424{
1425 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1426
1427 if (wm8753->dai_func < 4) {
1428 if (hifi)
1429 dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
1430 else
1431 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1432 }
1433 snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
1434}
1435
1436static void wm8753_work(struct work_struct *work) 1382static void wm8753_work(struct work_struct *work)
1437{ 1383{
1438 struct snd_soc_dapm_context *dapm = 1384 struct snd_soc_dapm_context *dapm =
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 3d4c55f3c7b5..ae1cadfae84c 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -223,11 +223,12 @@ struct wm8903_priv {
223 int fs; 223 int fs;
224 int deemph; 224 int deemph;
225 225
226 int dcs_pending;
227 int dcs_cache[4];
228
226 /* Reference count */ 229 /* Reference count */
227 int class_w_users; 230 int class_w_users;
228 231
229 struct completion wseq;
230
231 struct snd_soc_jack *mic_jack; 232 struct snd_soc_jack *mic_jack;
232 int mic_det; 233 int mic_det;
233 int mic_short; 234 int mic_short;
@@ -246,6 +247,12 @@ static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int re
246 case WM8903_REVISION_NUMBER: 247 case WM8903_REVISION_NUMBER:
247 case WM8903_INTERRUPT_STATUS_1: 248 case WM8903_INTERRUPT_STATUS_1:
248 case WM8903_WRITE_SEQUENCER_4: 249 case WM8903_WRITE_SEQUENCER_4:
250 case WM8903_POWER_MANAGEMENT_3:
251 case WM8903_POWER_MANAGEMENT_2:
252 case WM8903_DC_SERVO_READBACK_1:
253 case WM8903_DC_SERVO_READBACK_2:
254 case WM8903_DC_SERVO_READBACK_3:
255 case WM8903_DC_SERVO_READBACK_4:
249 return 1; 256 return 1;
250 257
251 default: 258 default:
@@ -253,50 +260,6 @@ static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int re
253 } 260 }
254} 261}
255 262
256static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
257{
258 u16 reg[5];
259 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
260
261 BUG_ON(start > 48);
262
263 /* Enable the sequencer if it's not already on */
264 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
265 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
266 reg[0] | WM8903_WSEQ_ENA);
267
268 dev_dbg(codec->dev, "Starting sequence at %d\n", start);
269
270 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
271 start | WM8903_WSEQ_START);
272
273 /* Wait for it to complete. If we have the interrupt wired up then
274 * that will break us out of the poll early.
275 */
276 do {
277 wait_for_completion_timeout(&wm8903->wseq,
278 msecs_to_jiffies(10));
279
280 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
281 } while (reg[4] & WM8903_WSEQ_BUSY);
282
283 dev_dbg(codec->dev, "Sequence complete\n");
284
285 /* Disable the sequencer again if we enabled it */
286 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
287
288 return 0;
289}
290
291static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
292{
293 int i;
294
295 /* There really ought to be something better we can do here :/ */
296 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
297 cache[i] = codec->hw_read(codec, i);
298}
299
300static void wm8903_reset(struct snd_soc_codec *codec) 263static void wm8903_reset(struct snd_soc_codec *codec)
301{ 264{
302 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); 265 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
@@ -304,11 +267,6 @@ static void wm8903_reset(struct snd_soc_codec *codec)
304 sizeof(wm8903_reg_defaults)); 267 sizeof(wm8903_reg_defaults));
305} 268}
306 269
307#define WM8903_OUTPUT_SHORT 0x8
308#define WM8903_OUTPUT_OUT 0x4
309#define WM8903_OUTPUT_INT 0x2
310#define WM8903_OUTPUT_IN 0x1
311
312static int wm8903_cp_event(struct snd_soc_dapm_widget *w, 270static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
313 struct snd_kcontrol *kcontrol, int event) 271 struct snd_kcontrol *kcontrol, int event)
314{ 272{
@@ -318,97 +276,101 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
318 return 0; 276 return 0;
319} 277}
320 278
321/* 279static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
322 * Event for headphone and line out amplifier power changes. Special 280 struct snd_kcontrol *kcontrol, int event)
323 * power up/down sequences are required in order to maximise pop/click
324 * performance.
325 */
326static int wm8903_output_event(struct snd_soc_dapm_widget *w,
327 struct snd_kcontrol *kcontrol, int event)
328{ 281{
329 struct snd_soc_codec *codec = w->codec; 282 struct snd_soc_codec *codec = w->codec;
330 u16 val; 283 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
331 u16 reg;
332 u16 dcs_reg;
333 u16 dcs_bit;
334 int shift;
335 284
336 switch (w->reg) { 285 switch (event) {
337 case WM8903_POWER_MANAGEMENT_2: 286 case SND_SOC_DAPM_POST_PMU:
338 reg = WM8903_ANALOGUE_HP_0; 287 wm8903->dcs_pending |= 1 << w->shift;
339 dcs_bit = 0 + w->shift;
340 break; 288 break;
341 case WM8903_POWER_MANAGEMENT_3: 289 case SND_SOC_DAPM_PRE_PMD:
342 reg = WM8903_ANALOGUE_LINEOUT_0; 290 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
343 dcs_bit = 2 + w->shift; 291 1 << w->shift, 0);
344 break; 292 break;
345 default:
346 BUG();
347 return -EINVAL; /* Spurious warning from some compilers */
348 } 293 }
349 294
350 switch (w->shift) { 295 return 0;
351 case 0: 296}
352 shift = 0;
353 break;
354 case 1:
355 shift = 4;
356 break;
357 default:
358 BUG();
359 return -EINVAL; /* Spurious warning from some compilers */
360 }
361 297
362 if (event & SND_SOC_DAPM_PRE_PMU) { 298#define WM8903_DCS_MODE_WRITE_STOP 0
363 val = snd_soc_read(codec, reg); 299#define WM8903_DCS_MODE_START_STOP 2
364 300
365 /* Short the output */ 301static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
366 val &= ~(WM8903_OUTPUT_SHORT << shift); 302 enum snd_soc_dapm_type event, int subseq)
367 snd_soc_write(codec, reg, val); 303{
368 } 304 struct snd_soc_codec *codec = container_of(dapm,
305 struct snd_soc_codec, dapm);
306 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
307 int dcs_mode = WM8903_DCS_MODE_WRITE_STOP;
308 int i, val;
369 309
370 if (event & SND_SOC_DAPM_POST_PMU) { 310 /* Complete any pending DC servo starts */
371 val = snd_soc_read(codec, reg); 311 if (wm8903->dcs_pending) {
312 dev_dbg(codec->dev, "Starting DC servo for %x\n",
313 wm8903->dcs_pending);
372 314
373 val |= (WM8903_OUTPUT_IN << shift); 315 /* If we've no cached values then we need to do startup */
374 snd_soc_write(codec, reg, val); 316 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
317 if (!(wm8903->dcs_pending & (1 << i)))
318 continue;
375 319
376 val |= (WM8903_OUTPUT_INT << shift); 320 if (wm8903->dcs_cache[i]) {
377 snd_soc_write(codec, reg, val); 321 dev_dbg(codec->dev,
322 "Restore DC servo %d value %x\n",
323 3 - i, wm8903->dcs_cache[i]);
324
325 snd_soc_write(codec, WM8903_DC_SERVO_4 + i,
326 wm8903->dcs_cache[i] & 0xff);
327 } else {
328 dev_dbg(codec->dev,
329 "Calibrate DC servo %d\n", 3 - i);
330 dcs_mode = WM8903_DCS_MODE_START_STOP;
331 }
332 }
378 333
379 /* Turn on the output ENA_OUTP */ 334 /* Don't trust the cache for analogue */
380 val |= (WM8903_OUTPUT_OUT << shift); 335 if (wm8903->class_w_users)
381 snd_soc_write(codec, reg, val); 336 dcs_mode = WM8903_DCS_MODE_START_STOP;
382 337
383 /* Enable the DC servo */ 338 snd_soc_update_bits(codec, WM8903_DC_SERVO_2,
384 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 339 WM8903_DCS_MODE_MASK, dcs_mode);
385 dcs_reg |= dcs_bit;
386 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
387 340
388 /* Remove the short */ 341 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
389 val |= (WM8903_OUTPUT_SHORT << shift); 342 WM8903_DCS_ENA_MASK, wm8903->dcs_pending);
390 snd_soc_write(codec, reg, val);
391 }
392 343
393 if (event & SND_SOC_DAPM_PRE_PMD) { 344 switch (dcs_mode) {
394 val = snd_soc_read(codec, reg); 345 case WM8903_DCS_MODE_WRITE_STOP:
346 break;
395 347
396 /* Short the output */ 348 case WM8903_DCS_MODE_START_STOP:
397 val &= ~(WM8903_OUTPUT_SHORT << shift); 349 msleep(270);
398 snd_soc_write(codec, reg, val);
399 350
400 /* Disable the DC servo */ 351 /* Cache the measured offsets for digital */
401 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 352 if (wm8903->class_w_users)
402 dcs_reg &= ~dcs_bit; 353 break;
403 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
404 354
405 /* Then disable the intermediate and output stages */ 355 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
406 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 356 if (!(wm8903->dcs_pending & (1 << i)))
407 WM8903_OUTPUT_IN) << shift); 357 continue;
408 snd_soc_write(codec, reg, val);
409 }
410 358
411 return 0; 359 val = snd_soc_read(codec,
360 WM8903_DC_SERVO_READBACK_1 + i);
361 dev_dbg(codec->dev, "DC servo %d: %x\n",
362 3 - i, val);
363 wm8903->dcs_cache[i] = val;
364 }
365 break;
366
367 default:
368 pr_warn("DCS mode %d delay not set\n", dcs_mode);
369 break;
370 }
371
372 wm8903->dcs_pending = 0;
373 }
412} 374}
413 375
414/* 376/*
@@ -674,6 +636,22 @@ static const struct soc_enum lsidetone_enum =
674static const struct soc_enum rsidetone_enum = 636static const struct soc_enum rsidetone_enum =
675 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); 637 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
676 638
639static const char *aif_text[] = {
640 "Left", "Right"
641};
642
643static const struct soc_enum lcapture_enum =
644 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text);
645
646static const struct soc_enum rcapture_enum =
647 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text);
648
649static const struct soc_enum lplay_enum =
650 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text);
651
652static const struct soc_enum rplay_enum =
653 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text);
654
677static const struct snd_kcontrol_new wm8903_snd_controls[] = { 655static const struct snd_kcontrol_new wm8903_snd_controls[] = {
678 656
679/* Input PGAs - No TLV since the scale depends on PGA mode */ 657/* Input PGAs - No TLV since the scale depends on PGA mode */
@@ -791,6 +769,18 @@ static const struct snd_kcontrol_new lsidetone_mux =
791static const struct snd_kcontrol_new rsidetone_mux = 769static const struct snd_kcontrol_new rsidetone_mux =
792 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); 770 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
793 771
772static const struct snd_kcontrol_new lcapture_mux =
773 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
774
775static const struct snd_kcontrol_new rcapture_mux =
776 SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum);
777
778static const struct snd_kcontrol_new lplay_mux =
779 SOC_DAPM_ENUM("Left Playback Mux", lplay_enum);
780
781static const struct snd_kcontrol_new rplay_mux =
782 SOC_DAPM_ENUM("Right Playback Mux", rplay_enum);
783
794static const struct snd_kcontrol_new left_output_mixer[] = { 784static const struct snd_kcontrol_new left_output_mixer[] = {
795SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 785SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
796SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), 786SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
@@ -854,14 +844,26 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
854SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), 844SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
855SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), 845SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
856 846
857SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), 847SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
858SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), 848SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
849
850SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux),
851SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux),
852
853SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
854SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
859 855
860SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), 856SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
861SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), 857SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
862 858
863SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), 859SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0),
864SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), 860SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0),
861
862SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux),
863SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux),
864
865SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0),
866SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0),
865 867
866SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, 868SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
867 left_output_mixer, ARRAY_SIZE(left_output_mixer)), 869 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
@@ -873,23 +875,45 @@ SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
873SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, 875SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
874 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), 876 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
875 877
876SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 878SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0,
877 1, 0, NULL, 0, wm8903_output_event, 879 4, 0, NULL, 0),
878 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 880SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0,
879 SND_SOC_DAPM_PRE_PMD), 881 0, 0, NULL, 0),
880SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 882
881 0, 0, NULL, 0, wm8903_output_event, 883SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 4, 0,
882 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 884 NULL, 0),
883 SND_SOC_DAPM_PRE_PMD), 885SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 0, 0,
884 886 NULL, 0),
885SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, 887
886 NULL, 0, wm8903_output_event, 888SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0),
887 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 889SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0),
888 SND_SOC_DAPM_PRE_PMD), 890SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0),
889SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, 891SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0),
890 NULL, 0, wm8903_output_event, 892SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0),
891 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 893SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0),
892 SND_SOC_DAPM_PRE_PMD), 894
895SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0,
896 NULL, 0),
897SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0,
898 NULL, 0),
899SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 5, 0,
900 NULL, 0),
901SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0,
902 NULL, 0),
903SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0,
904 NULL, 0),
905SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 1, 0,
906 NULL, 0),
907
908SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0),
909SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event,
910 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
911SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event,
912 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
913SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event,
914 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
915SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event,
916 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
893 917
894SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, 918SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
895 NULL, 0), 919 NULL, 0),
@@ -899,10 +923,18 @@ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
899SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, 923SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
900 wm8903_cp_event, SND_SOC_DAPM_POST_PMU), 924 wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
901SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), 925SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
926SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
902}; 927};
903 928
904static const struct snd_soc_dapm_route intercon[] = { 929static const struct snd_soc_dapm_route intercon[] = {
905 930
931 { "CLK_DSP", NULL, "CLK_SYS" },
932 { "Mic Bias", NULL, "CLK_SYS" },
933 { "HPL_DCS", NULL, "CLK_SYS" },
934 { "HPR_DCS", NULL, "CLK_SYS" },
935 { "LINEOUTL_DCS", NULL, "CLK_SYS" },
936 { "LINEOUTR_DCS", NULL, "CLK_SYS" },
937
906 { "Left Input Mux", "IN1L", "IN1L" }, 938 { "Left Input Mux", "IN1L", "IN1L" },
907 { "Left Input Mux", "IN2L", "IN2L" }, 939 { "Left Input Mux", "IN2L", "IN2L" },
908 { "Left Input Mux", "IN3L", "IN3L" }, 940 { "Left Input Mux", "IN3L", "IN3L" },
@@ -943,18 +975,36 @@ static const struct snd_soc_dapm_route intercon[] = {
943 { "Left Input PGA", NULL, "Left Input Mode Mux" }, 975 { "Left Input PGA", NULL, "Left Input Mode Mux" },
944 { "Right Input PGA", NULL, "Right Input Mode Mux" }, 976 { "Right Input PGA", NULL, "Right Input Mode Mux" },
945 977
978 { "Left Capture Mux", "Left", "ADCL" },
979 { "Left Capture Mux", "Right", "ADCR" },
980
981 { "Right Capture Mux", "Left", "ADCL" },
982 { "Right Capture Mux", "Right", "ADCR" },
983
984 { "AIFTXL", NULL, "Left Capture Mux" },
985 { "AIFTXR", NULL, "Right Capture Mux" },
986
946 { "ADCL", NULL, "Left Input PGA" }, 987 { "ADCL", NULL, "Left Input PGA" },
947 { "ADCL", NULL, "CLK_DSP" }, 988 { "ADCL", NULL, "CLK_DSP" },
948 { "ADCR", NULL, "Right Input PGA" }, 989 { "ADCR", NULL, "Right Input PGA" },
949 { "ADCR", NULL, "CLK_DSP" }, 990 { "ADCR", NULL, "CLK_DSP" },
950 991
992 { "Left Playback Mux", "Left", "AIFRXL" },
993 { "Left Playback Mux", "Right", "AIFRXR" },
994
995 { "Right Playback Mux", "Left", "AIFRXL" },
996 { "Right Playback Mux", "Right", "AIFRXR" },
997
951 { "DACL Sidetone", "Left", "ADCL" }, 998 { "DACL Sidetone", "Left", "ADCL" },
952 { "DACL Sidetone", "Right", "ADCR" }, 999 { "DACL Sidetone", "Right", "ADCR" },
953 { "DACR Sidetone", "Left", "ADCL" }, 1000 { "DACR Sidetone", "Left", "ADCL" },
954 { "DACR Sidetone", "Right", "ADCR" }, 1001 { "DACR Sidetone", "Right", "ADCR" },
955 1002
1003 { "DACL", NULL, "Left Playback Mux" },
956 { "DACL", NULL, "DACL Sidetone" }, 1004 { "DACL", NULL, "DACL Sidetone" },
957 { "DACL", NULL, "CLK_DSP" }, 1005 { "DACL", NULL, "CLK_DSP" },
1006
1007 { "DACR", NULL, "Right Playback Mux" },
958 { "DACR", NULL, "DACR Sidetone" }, 1008 { "DACR", NULL, "DACR Sidetone" },
959 { "DACR", NULL, "CLK_DSP" }, 1009 { "DACR", NULL, "CLK_DSP" },
960 1010
@@ -987,11 +1037,35 @@ static const struct snd_soc_dapm_route intercon[] = {
987 { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, 1037 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
988 { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, 1038 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
989 1039
990 { "HPOUTL", NULL, "Left Headphone Output PGA" }, 1040 { "HPL_ENA_DLY", NULL, "Left Headphone Output PGA" },
991 { "HPOUTR", NULL, "Right Headphone Output PGA" }, 1041 { "HPR_ENA_DLY", NULL, "Right Headphone Output PGA" },
1042 { "LINEOUTL_ENA_DLY", NULL, "Left Line Output PGA" },
1043 { "LINEOUTR_ENA_DLY", NULL, "Right Line Output PGA" },
1044
1045 { "HPL_DCS", NULL, "DCS Master" },
1046 { "HPR_DCS", NULL, "DCS Master" },
1047 { "LINEOUTL_DCS", NULL, "DCS Master" },
1048 { "LINEOUTR_DCS", NULL, "DCS Master" },
992 1049
993 { "LINEOUTL", NULL, "Left Line Output PGA" }, 1050 { "HPL_DCS", NULL, "HPL_ENA_DLY" },
994 { "LINEOUTR", NULL, "Right Line Output PGA" }, 1051 { "HPR_DCS", NULL, "HPR_ENA_DLY" },
1052 { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" },
1053 { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" },
1054
1055 { "HPL_ENA_OUTP", NULL, "HPL_DCS" },
1056 { "HPR_ENA_OUTP", NULL, "HPR_DCS" },
1057 { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" },
1058 { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" },
1059
1060 { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" },
1061 { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" },
1062 { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" },
1063 { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" },
1064
1065 { "HPOUTL", NULL, "HPL_RMV_SHORT" },
1066 { "HPOUTR", NULL, "HPR_RMV_SHORT" },
1067 { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" },
1068 { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" },
995 1069
996 { "LOP", NULL, "Left Speaker PGA" }, 1070 { "LOP", NULL, "Left Speaker PGA" },
997 { "LON", NULL, "Left Speaker PGA" }, 1071 { "LON", NULL, "Left Speaker PGA" },
@@ -1019,29 +1093,71 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
1019static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1093static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1020 enum snd_soc_bias_level level) 1094 enum snd_soc_bias_level level)
1021{ 1095{
1022 u16 reg;
1023
1024 switch (level) { 1096 switch (level) {
1025 case SND_SOC_BIAS_ON: 1097 case SND_SOC_BIAS_ON:
1098 break;
1099
1026 case SND_SOC_BIAS_PREPARE: 1100 case SND_SOC_BIAS_PREPARE:
1027 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1101 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1028 reg &= ~(WM8903_VMID_RES_MASK); 1102 WM8903_VMID_RES_MASK,
1029 reg |= WM8903_VMID_RES_50K; 1103 WM8903_VMID_RES_50K);
1030 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1031 break; 1104 break;
1032 1105
1033 case SND_SOC_BIAS_STANDBY: 1106 case SND_SOC_BIAS_STANDBY:
1034 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1107 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1035 snd_soc_write(codec, WM8903_CLOCK_RATES_2, 1108 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1036 WM8903_CLK_SYS_ENA); 1109 WM8903_POBCTRL | WM8903_ISEL_MASK |
1037 1110 WM8903_STARTUP_BIAS_ENA |
1038 /* Change DC servo dither level in startup sequence */ 1111 WM8903_BIAS_ENA,
1039 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); 1112 WM8903_POBCTRL |
1040 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); 1113 (2 << WM8903_ISEL_SHIFT) |
1041 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); 1114 WM8903_STARTUP_BIAS_ENA);
1042 1115
1043 wm8903_run_sequence(codec, 0); 1116 snd_soc_update_bits(codec,
1044 wm8903_sync_reg_cache(codec, codec->reg_cache); 1117 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1118 WM8903_SPK_DISCHARGE,
1119 WM8903_SPK_DISCHARGE);
1120
1121 msleep(33);
1122
1123 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1124 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1125 WM8903_SPKL_ENA | WM8903_SPKR_ENA);
1126
1127 snd_soc_update_bits(codec,
1128 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1129 WM8903_SPK_DISCHARGE, 0);
1130
1131 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1132 WM8903_VMID_TIE_ENA |
1133 WM8903_BUFIO_ENA |
1134 WM8903_VMID_IO_ENA |
1135 WM8903_VMID_SOFT_MASK |
1136 WM8903_VMID_RES_MASK |
1137 WM8903_VMID_BUF_ENA,
1138 WM8903_VMID_TIE_ENA |
1139 WM8903_BUFIO_ENA |
1140 WM8903_VMID_IO_ENA |
1141 (2 << WM8903_VMID_SOFT_SHIFT) |
1142 WM8903_VMID_RES_250K |
1143 WM8903_VMID_BUF_ENA);
1144
1145 msleep(129);
1146
1147 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1148 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1149 0);
1150
1151 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1152 WM8903_VMID_SOFT_MASK, 0);
1153
1154 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1155 WM8903_VMID_RES_MASK,
1156 WM8903_VMID_RES_50K);
1157
1158 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1159 WM8903_BIAS_ENA | WM8903_POBCTRL,
1160 WM8903_BIAS_ENA);
1045 1161
1046 /* By default no bypass paths are enabled so 1162 /* By default no bypass paths are enabled so
1047 * enable Class W support. 1163 * enable Class W support.
@@ -1054,17 +1170,32 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1054 WM8903_CP_DYN_V); 1170 WM8903_CP_DYN_V);
1055 } 1171 }
1056 1172
1057 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1173 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1058 reg &= ~(WM8903_VMID_RES_MASK); 1174 WM8903_VMID_RES_MASK,
1059 reg |= WM8903_VMID_RES_250K; 1175 WM8903_VMID_RES_250K);
1060 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1061 break; 1176 break;
1062 1177
1063 case SND_SOC_BIAS_OFF: 1178 case SND_SOC_BIAS_OFF:
1064 wm8903_run_sequence(codec, 32); 1179 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1065 reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2); 1180 WM8903_BIAS_ENA, 0);
1066 reg &= ~WM8903_CLK_SYS_ENA; 1181
1067 snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg); 1182 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1183 WM8903_VMID_SOFT_MASK,
1184 2 << WM8903_VMID_SOFT_SHIFT);
1185
1186 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1187 WM8903_VMID_BUF_ENA, 0);
1188
1189 msleep(290);
1190
1191 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1192 WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA |
1193 WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK |
1194 WM8903_VMID_SOFT_MASK |
1195 WM8903_VMID_BUF_ENA, 0);
1196
1197 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1198 WM8903_STARTUP_BIAS_ENA, 0);
1068 break; 1199 break;
1069 } 1200 }
1070 1201
@@ -1489,7 +1620,7 @@ int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
1489 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, 1620 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
1490 irq_mask); 1621 irq_mask);
1491 1622
1492 if (det && shrt) { 1623 if (det || shrt) {
1493 /* Enable mic detection, this may not have been set through 1624 /* Enable mic detection, this may not have been set through
1494 * platform data (eg, if the defaults are OK). */ 1625 * platform data (eg, if the defaults are OK). */
1495 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1626 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
@@ -1517,8 +1648,7 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1517 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; 1648 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1518 1649
1519 if (int_val & WM8903_WSEQ_BUSY_EINT) { 1650 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1520 dev_dbg(codec->dev, "Write sequencer done\n"); 1651 dev_warn(codec->dev, "Write sequencer done\n");
1521 complete(&wm8903->wseq);
1522 } 1652 }
1523 1653
1524 /* 1654 /*
@@ -1765,7 +1895,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1765 u16 val; 1895 u16 val;
1766 1896
1767 wm8903->codec = codec; 1897 wm8903->codec = codec;
1768 init_completion(&wm8903->wseq);
1769 1898
1770 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1899 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1771 if (ret != 0) { 1900 if (ret != 0) {
@@ -1781,19 +1910,33 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1781 } 1910 }
1782 1911
1783 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); 1912 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1784 dev_info(codec->dev, "WM8903 revision %d\n", 1913 dev_info(codec->dev, "WM8903 revision %c\n",
1785 val & WM8903_CHIP_REV_MASK); 1914 (val & WM8903_CHIP_REV_MASK) + 'A');
1786 1915
1787 wm8903_reset(codec); 1916 wm8903_reset(codec);
1788 1917
1789 /* Set up GPIOs and microphone detection */ 1918 /* Set up GPIOs and microphone detection */
1790 if (pdata) { 1919 if (pdata) {
1920 bool mic_gpio = false;
1921
1791 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { 1922 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1792 if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG) 1923 if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG)
1793 continue; 1924 continue;
1794 1925
1795 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, 1926 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1796 pdata->gpio_cfg[i] & 0xffff); 1927 pdata->gpio_cfg[i] & 0xffff);
1928
1929 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
1930 >> WM8903_GP1_FN_SHIFT;
1931
1932 switch (val) {
1933 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
1934 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
1935 mic_gpio = true;
1936 break;
1937 default:
1938 break;
1939 }
1797 } 1940 }
1798 1941
1799 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, 1942 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
@@ -1804,6 +1947,14 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1804 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1947 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1805 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); 1948 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1806 1949
1950 /* If microphone detection is enabled by pdata but
1951 * detected via IRQ then interrupts can be lost before
1952 * the machine driver has set up microphone detection
1953 * IRQs as the IRQs are clear on read. The detection
1954 * will be enabled when the machine driver configures.
1955 */
1956 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
1957
1807 wm8903->mic_delay = pdata->micdet_delay; 1958 wm8903->mic_delay = pdata->micdet_delay;
1808 } 1959 }
1809 1960
@@ -1863,9 +2014,9 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1863 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); 2014 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1864 2015
1865 /* Enable DAC soft mute by default */ 2016 /* Enable DAC soft mute by default */
1866 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 2017 snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
1867 val |= WM8903_DAC_MUTEMODE; 2018 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
1868 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); 2019 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
1869 2020
1870 snd_soc_add_controls(codec, wm8903_snd_controls, 2021 snd_soc_add_controls(codec, wm8903_snd_controls,
1871 ARRAY_SIZE(wm8903_snd_controls)); 2022 ARRAY_SIZE(wm8903_snd_controls));
@@ -1894,6 +2045,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1894 .reg_word_size = sizeof(u16), 2045 .reg_word_size = sizeof(u16),
1895 .reg_cache_default = wm8903_reg_defaults, 2046 .reg_cache_default = wm8903_reg_defaults,
1896 .volatile_register = wm8903_volatile_register, 2047 .volatile_register = wm8903_volatile_register,
2048 .seq_notifier = wm8903_seq_notifier,
1897}; 2049};
1898 2050
1899#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2051#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1932,7 +2084,7 @@ MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1932 2084
1933static struct i2c_driver wm8903_i2c_driver = { 2085static struct i2c_driver wm8903_i2c_driver = {
1934 .driver = { 2086 .driver = {
1935 .name = "wm8903-codec", 2087 .name = "wm8903",
1936 .owner = THIS_MODULE, 2088 .owner = THIS_MODULE,
1937 }, 2089 },
1938 .probe = wm8903_i2c_probe, 2090 .probe = wm8903_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index e8490f3edd03..db949311c0f2 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -75,6 +75,14 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41 75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
76#define WM8903_DC_SERVO_0 0x43 76#define WM8903_DC_SERVO_0 0x43
77#define WM8903_DC_SERVO_2 0x45 77#define WM8903_DC_SERVO_2 0x45
78#define WM8903_DC_SERVO_4 0x47
79#define WM8903_DC_SERVO_5 0x48
80#define WM8903_DC_SERVO_6 0x49
81#define WM8903_DC_SERVO_7 0x4A
82#define WM8903_DC_SERVO_READBACK_1 0x51
83#define WM8903_DC_SERVO_READBACK_2 0x52
84#define WM8903_DC_SERVO_READBACK_3 0x53
85#define WM8903_DC_SERVO_READBACK_4 0x54
78#define WM8903_ANALOGUE_HP_0 0x5A 86#define WM8903_ANALOGUE_HP_0 0x5A
79#define WM8903_ANALOGUE_LINEOUT_0 0x5E 87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
80#define WM8903_CHARGE_PUMP_0 0x62 88#define WM8903_CHARGE_PUMP_0 0x62
@@ -165,7 +173,7 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
165 173
166#define WM8903_VMID_RES_50K 2 174#define WM8903_VMID_RES_50K 2
167#define WM8903_VMID_RES_250K 3 175#define WM8903_VMID_RES_250K 3
168#define WM8903_VMID_RES_5K 4 176#define WM8903_VMID_RES_5K 6
169 177
170/* 178/*
171 * R8 (0x08) - Analogue DAC 0 179 * R8 (0x08) - Analogue DAC 0
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 30fb48ec2799..85e3e630e763 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -93,6 +93,7 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0); 93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0); 94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1); 95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
96static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);
96 97
97static const struct snd_kcontrol_new wm8978_snd_controls[] = { 98static const struct snd_kcontrol_new wm8978_snd_controls[] = {
98 99
@@ -144,19 +145,19 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
144 145
145 SOC_SINGLE("DAC Playback Limiter Threshold", 146 SOC_SINGLE("DAC Playback Limiter Threshold",
146 WM8978_DAC_LIMITER_2, 4, 7, 0), 147 WM8978_DAC_LIMITER_2, 4, 7, 0),
147 SOC_SINGLE("DAC Playback Limiter Boost", 148 SOC_SINGLE_TLV("DAC Playback Limiter Volume",
148 WM8978_DAC_LIMITER_2, 0, 15, 0), 149 WM8978_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),
149 150
150 SOC_ENUM("ALC Enable Switch", alc1), 151 SOC_ENUM("ALC Enable Switch", alc1),
151 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0), 152 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
152 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0), 153 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
153 154
154 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0), 155 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 10, 0),
155 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0), 156 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
156 157
157 SOC_ENUM("ALC Capture Mode", alc3), 158 SOC_ENUM("ALC Capture Mode", alc3),
158 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0), 159 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 10, 0),
159 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0), 160 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 10, 0),
160 161
161 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0), 162 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
162 SOC_SINGLE("ALC Capture Noise Gate Threshold", 163 SOC_SINGLE("ALC Capture Noise Gate Threshold",
@@ -211,8 +212,10 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
211 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1), 212 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
212 213
213 /* DAC / ADC oversampling */ 214 /* DAC / ADC oversampling */
214 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0), 215 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL,
215 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0), 216 5, 1, 0),
217 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL,
218 5, 1, 0),
216}; 219};
217 220
218/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */ 221/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
index 68e9b024dd48..a87adbd05ee1 100644
--- a/sound/soc/codecs/wm8994-tables.c
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -62,8 +62,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ 62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
63 { 0x000F, 0x000F }, /* R59 - LDO 1 */ 63 { 0x000F, 0x000F }, /* R59 - LDO 1 */
64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */ 64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */
65 { 0x0000, 0x0000 }, /* R61 */ 65 { 0xFFFF, 0xFFFF }, /* R61 */
66 { 0x0000, 0x0000 }, /* R62 */ 66 { 0xFFFF, 0xFFFF }, /* R62 */
67 { 0x0000, 0x0000 }, /* R63 */ 67 { 0x0000, 0x0000 }, /* R63 */
68 { 0x0000, 0x0000 }, /* R64 */ 68 { 0x0000, 0x0000 }, /* R64 */
69 { 0x0000, 0x0000 }, /* R65 */ 69 { 0x0000, 0x0000 }, /* R65 */
@@ -209,9 +209,9 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
209 { 0x0000, 0x0000 }, /* R205 */ 209 { 0x0000, 0x0000 }, /* R205 */
210 { 0x0000, 0x0000 }, /* R206 */ 210 { 0x0000, 0x0000 }, /* R206 */
211 { 0x0000, 0x0000 }, /* R207 */ 211 { 0x0000, 0x0000 }, /* R207 */
212 { 0x0000, 0x0000 }, /* R208 */ 212 { 0xFFFF, 0xFFFF }, /* R208 */
213 { 0x0000, 0x0000 }, /* R209 */ 213 { 0xFFFF, 0xFFFF }, /* R209 */
214 { 0x0000, 0x0000 }, /* R210 */ 214 { 0xFFFF, 0xFFFF }, /* R210 */
215 { 0x0000, 0x0000 }, /* R211 */ 215 { 0x0000, 0x0000 }, /* R211 */
216 { 0x0000, 0x0000 }, /* R212 */ 216 { 0x0000, 0x0000 }, /* R212 */
217 { 0x0000, 0x0000 }, /* R213 */ 217 { 0x0000, 0x0000 }, /* R213 */
@@ -1573,7 +1573,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ 1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
1574}; 1574};
1575 1575
1576const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { 1576const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1577 0x8994, /* R0 - Software Reset */ 1577 0x8994, /* R0 - Software Reset */
1578 0x0000, /* R1 - Power Management (1) */ 1578 0x0000, /* R1 - Power Management (1) */
1579 0x6000, /* R2 - Power Management (2) */ 1579 0x6000, /* R2 - Power Management (2) */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 0ca81d3c64e8..3dc64c8b6a5c 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -102,11 +102,16 @@ struct wm8994_priv {
102 102
103 wm8958_micdet_cb jack_cb; 103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data; 104 void *jack_cb_data;
105 bool jack_is_mic; 105 int micdet_irq;
106 bool jack_is_video;
107 106
108 int revision; 107 int revision;
109 struct wm8994_pdata *pdata; 108 struct wm8994_pdata *pdata;
109
110 unsigned int aif1clk_enable:1;
111 unsigned int aif2clk_enable:1;
112
113 unsigned int aif1clk_disable:1;
114 unsigned int aif2clk_disable:1;
110}; 115};
111 116
112static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) 117static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
@@ -523,7 +528,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
523 struct snd_ctl_elem_value *ucontrol) 528 struct snd_ctl_elem_value *ucontrol)
524{ 529{
525 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 530 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
526 struct wm8994_priv *wm8994 =snd_soc_codec_get_drvdata(codec); 531 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
527 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 532 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
528 533
529 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; 534 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -1004,6 +1009,117 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
1004 } 1009 }
1005} 1010}
1006 1011
1012static int late_enable_ev(struct snd_soc_dapm_widget *w,
1013 struct snd_kcontrol *kcontrol, int event)
1014{
1015 struct snd_soc_codec *codec = w->codec;
1016 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1017
1018 switch (event) {
1019 case SND_SOC_DAPM_PRE_PMU:
1020 if (wm8994->aif1clk_enable) {
1021 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
1022 WM8994_AIF1CLK_ENA_MASK,
1023 WM8994_AIF1CLK_ENA);
1024 wm8994->aif1clk_enable = 0;
1025 }
1026 if (wm8994->aif2clk_enable) {
1027 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
1028 WM8994_AIF2CLK_ENA_MASK,
1029 WM8994_AIF2CLK_ENA);
1030 wm8994->aif2clk_enable = 0;
1031 }
1032 break;
1033 }
1034
1035 return 0;
1036}
1037
1038static int late_disable_ev(struct snd_soc_dapm_widget *w,
1039 struct snd_kcontrol *kcontrol, int event)
1040{
1041 struct snd_soc_codec *codec = w->codec;
1042 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1043
1044 switch (event) {
1045 case SND_SOC_DAPM_POST_PMD:
1046 if (wm8994->aif1clk_disable) {
1047 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
1048 WM8994_AIF1CLK_ENA_MASK, 0);
1049 wm8994->aif1clk_disable = 0;
1050 }
1051 if (wm8994->aif2clk_disable) {
1052 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
1053 WM8994_AIF2CLK_ENA_MASK, 0);
1054 wm8994->aif2clk_disable = 0;
1055 }
1056 break;
1057 }
1058
1059 return 0;
1060}
1061
1062static int aif1clk_ev(struct snd_soc_dapm_widget *w,
1063 struct snd_kcontrol *kcontrol, int event)
1064{
1065 struct snd_soc_codec *codec = w->codec;
1066 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1067
1068 switch (event) {
1069 case SND_SOC_DAPM_PRE_PMU:
1070 wm8994->aif1clk_enable = 1;
1071 break;
1072 case SND_SOC_DAPM_POST_PMD:
1073 wm8994->aif1clk_disable = 1;
1074 break;
1075 }
1076
1077 return 0;
1078}
1079
1080static int aif2clk_ev(struct snd_soc_dapm_widget *w,
1081 struct snd_kcontrol *kcontrol, int event)
1082{
1083 struct snd_soc_codec *codec = w->codec;
1084 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1085
1086 switch (event) {
1087 case SND_SOC_DAPM_PRE_PMU:
1088 wm8994->aif2clk_enable = 1;
1089 break;
1090 case SND_SOC_DAPM_POST_PMD:
1091 wm8994->aif2clk_disable = 1;
1092 break;
1093 }
1094
1095 return 0;
1096}
1097
1098static int adc_mux_ev(struct snd_soc_dapm_widget *w,
1099 struct snd_kcontrol *kcontrol, int event)
1100{
1101 late_enable_ev(w, kcontrol, event);
1102 return 0;
1103}
1104
1105static int micbias_ev(struct snd_soc_dapm_widget *w,
1106 struct snd_kcontrol *kcontrol, int event)
1107{
1108 late_enable_ev(w, kcontrol, event);
1109 return 0;
1110}
1111
1112static int dac_ev(struct snd_soc_dapm_widget *w,
1113 struct snd_kcontrol *kcontrol, int event)
1114{
1115 struct snd_soc_codec *codec = w->codec;
1116 unsigned int mask = 1 << w->shift;
1117
1118 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
1119 mask, mask);
1120 return 0;
1121}
1122
1007static const char *hp_mux_text[] = { 1123static const char *hp_mux_text[] = {
1008 "Mixer", 1124 "Mixer",
1009 "DAC", 1125 "DAC",
@@ -1272,11 +1388,68 @@ static const struct soc_enum aif2dacr_src_enum =
1272static const struct snd_kcontrol_new aif2dacr_src_mux = 1388static const struct snd_kcontrol_new aif2dacr_src_mux =
1273 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); 1389 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
1274 1390
1391static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = {
1392SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev,
1393 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1394SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev,
1395 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1396
1397SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1398 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1399SND_SOC_DAPM_PGA_E("Late DAC1R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1400 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1401SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1402 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1403SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1404 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1405
1406SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
1407};
1408
1409static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
1410SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
1411SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0)
1412};
1413
1414static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
1415SND_SOC_DAPM_DAC_E("DAC2L", NULL, SND_SOC_NOPM, 3, 0,
1416 dac_ev, SND_SOC_DAPM_PRE_PMU),
1417SND_SOC_DAPM_DAC_E("DAC2R", NULL, SND_SOC_NOPM, 2, 0,
1418 dac_ev, SND_SOC_DAPM_PRE_PMU),
1419SND_SOC_DAPM_DAC_E("DAC1L", NULL, SND_SOC_NOPM, 1, 0,
1420 dac_ev, SND_SOC_DAPM_PRE_PMU),
1421SND_SOC_DAPM_DAC_E("DAC1R", NULL, SND_SOC_NOPM, 0, 0,
1422 dac_ev, SND_SOC_DAPM_PRE_PMU),
1423};
1424
1425static const struct snd_soc_dapm_widget wm8994_dac_widgets[] = {
1426SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
1427SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
1428SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
1429SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
1430};
1431
1432static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = {
1433SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux,
1434 adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
1435SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux,
1436 adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
1437};
1438
1439static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = {
1440SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
1441SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
1442};
1443
1275static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 1444static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
1276SND_SOC_DAPM_INPUT("DMIC1DAT"), 1445SND_SOC_DAPM_INPUT("DMIC1DAT"),
1277SND_SOC_DAPM_INPUT("DMIC2DAT"), 1446SND_SOC_DAPM_INPUT("DMIC2DAT"),
1278SND_SOC_DAPM_INPUT("Clock"), 1447SND_SOC_DAPM_INPUT("Clock"),
1279 1448
1449SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0),
1450SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1451 SND_SOC_DAPM_PRE_PMU),
1452
1280SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1453SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1281 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1454 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1282 1455
@@ -1284,12 +1457,9 @@ SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
1284SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), 1457SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
1285SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), 1458SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
1286 1459
1287SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), 1460SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
1288SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
1289
1290SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
1291 0, WM8994_POWER_MANAGEMENT_4, 9, 0), 1461 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
1292SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 1462SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
1293 0, WM8994_POWER_MANAGEMENT_4, 8, 0), 1463 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
1294SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, 1464SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
1295 WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, 1465 WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
@@ -1298,9 +1468,9 @@ SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
1298 WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, 1468 WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
1299 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1469 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1300 1470
1301SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", 1471SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL,
1302 0, WM8994_POWER_MANAGEMENT_4, 11, 0), 1472 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
1303SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 1473SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL,
1304 0, WM8994_POWER_MANAGEMENT_4, 10, 0), 1474 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
1305SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, 1475SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
1306 WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, 1476 WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
@@ -1345,6 +1515,7 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
1345 1515
1346SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1516SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1347SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 1517SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
1518SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1348SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 1519SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
1349 1520
1350SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1521SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
@@ -1368,14 +1539,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
1368SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), 1539SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
1369SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), 1540SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1370 1541
1371SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
1372SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
1373
1374SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
1375SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
1376SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
1377SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
1378
1379SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), 1542SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1380SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), 1543SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1381 1544
@@ -1515,14 +1678,12 @@ static const struct snd_soc_dapm_route intercon[] = {
1515 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, 1678 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
1516 1679
1517 /* DAC1 inputs */ 1680 /* DAC1 inputs */
1518 { "DAC1L", NULL, "DAC1L Mixer" },
1519 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, 1681 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
1520 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, 1682 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
1521 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, 1683 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
1522 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, 1684 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1523 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1685 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1524 1686
1525 { "DAC1R", NULL, "DAC1R Mixer" },
1526 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, 1687 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
1527 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, 1688 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
1528 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, 1689 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
@@ -1531,7 +1692,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1531 1692
1532 /* DAC2/AIF2 outputs */ 1693 /* DAC2/AIF2 outputs */
1533 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, 1694 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
1534 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
1535 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, 1695 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
1536 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, 1696 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
1537 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, 1697 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
@@ -1539,13 +1699,17 @@ static const struct snd_soc_dapm_route intercon[] = {
1539 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1699 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1540 1700
1541 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, 1701 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
1542 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
1543 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, 1702 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
1544 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, 1703 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
1545 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, 1704 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
1546 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, 1705 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1547 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1706 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1548 1707
1708 { "AIF1ADCDAT", NULL, "AIF1ADC1L" },
1709 { "AIF1ADCDAT", NULL, "AIF1ADC1R" },
1710 { "AIF1ADCDAT", NULL, "AIF1ADC2L" },
1711 { "AIF1ADCDAT", NULL, "AIF1ADC2R" },
1712
1549 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, 1713 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
1550 1714
1551 /* AIF3 output */ 1715 /* AIF3 output */
@@ -1578,6 +1742,33 @@ static const struct snd_soc_dapm_route intercon[] = {
1578 { "Right Headphone Mux", "DAC", "DAC1R" }, 1742 { "Right Headphone Mux", "DAC", "DAC1R" },
1579}; 1743};
1580 1744
1745static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = {
1746 { "DAC1L", NULL, "Late DAC1L Enable PGA" },
1747 { "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" },
1748 { "DAC1R", NULL, "Late DAC1R Enable PGA" },
1749 { "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" },
1750 { "DAC2L", NULL, "Late DAC2L Enable PGA" },
1751 { "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" },
1752 { "DAC2R", NULL, "Late DAC2R Enable PGA" },
1753 { "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" }
1754};
1755
1756static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = {
1757 { "DAC1L", NULL, "DAC1L Mixer" },
1758 { "DAC1R", NULL, "DAC1R Mixer" },
1759 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
1760 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
1761};
1762
1763static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1764 { "AIF1DACDAT", NULL, "AIF2DACDAT" },
1765 { "AIF2DACDAT", NULL, "AIF1DACDAT" },
1766 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
1767 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
1768 { "MICBIAS", NULL, "CLK_SYS" },
1769 { "MICBIAS", NULL, "MICBIAS Supply" },
1770};
1771
1581static const struct snd_soc_dapm_route wm8994_intercon[] = { 1772static const struct snd_soc_dapm_route wm8994_intercon[] = {
1582 { "AIF2DACL", NULL, "AIF2DAC Mux" }, 1773 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1583 { "AIF2DACR", NULL, "AIF2DAC Mux" }, 1774 { "AIF2DACR", NULL, "AIF2DAC Mux" },
@@ -2501,6 +2692,22 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2501{ 2692{
2502 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2693 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2503 int i, ret; 2694 int i, ret;
2695 unsigned int val, mask;
2696
2697 if (wm8994->revision < 4) {
2698 /* force a HW read */
2699 val = wm8994_reg_read(codec->control_data,
2700 WM8994_POWER_MANAGEMENT_5);
2701
2702 /* modify the cache only */
2703 codec->cache_only = 1;
2704 mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA |
2705 WM8994_DAC2R_ENA | WM8994_DAC2L_ENA;
2706 val &= mask;
2707 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
2708 mask, val);
2709 codec->cache_only = 0;
2710 }
2504 2711
2505 /* Restore the registers */ 2712 /* Restore the registers */
2506 ret = snd_soc_cache_sync(codec); 2713 ret = snd_soc_cache_sync(codec);
@@ -2688,6 +2895,13 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2688 else 2895 else
2689 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, 2896 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
2690 ARRAY_SIZE(wm8994_eq_controls)); 2897 ARRAY_SIZE(wm8994_eq_controls));
2898
2899 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
2900 if (pdata->micbias[i]) {
2901 snd_soc_write(codec, WM8958_MICBIAS1 + i,
2902 pdata->micbias[i] & 0xffff);
2903 }
2904 }
2691} 2905}
2692 2906
2693/** 2907/**
@@ -2798,47 +3012,18 @@ static void wm8958_default_micdet(u16 status, void *data)
2798 int report = 0; 3012 int report = 0;
2799 3013
2800 /* If nothing present then clear our statuses */ 3014 /* If nothing present then clear our statuses */
2801 if (!(status & WM8958_MICD_STS)) { 3015 if (!(status & WM8958_MICD_STS))
2802 wm8994->jack_is_video = false;
2803 wm8994->jack_is_mic = false;
2804 goto done; 3016 goto done;
2805 }
2806
2807 /* Assume anything over 475 ohms is a microphone and remember
2808 * that we've seen one (since buttons override it) */
2809 if (status & 0x600)
2810 wm8994->jack_is_mic = true;
2811 if (wm8994->jack_is_mic)
2812 report |= SND_JACK_MICROPHONE;
2813 3017
2814 /* Video has an impedence of approximately 75 ohms; assume 3018 report = SND_JACK_MICROPHONE;
2815 * this isn't used as a button and remember it since buttons
2816 * override it. */
2817 if (status & 0x40)
2818 wm8994->jack_is_video = true;
2819 if (wm8994->jack_is_video)
2820 report |= SND_JACK_VIDEOOUT;
2821 3019
2822 /* Everything else is buttons; just assign slots */ 3020 /* Everything else is buttons; just assign slots */
2823 if (status & 0x4) 3021 if (status & 0x1c0)
2824 report |= SND_JACK_BTN_0; 3022 report |= SND_JACK_BTN_0;
2825 if (status & 0x8)
2826 report |= SND_JACK_BTN_1;
2827 if (status & 0x10)
2828 report |= SND_JACK_BTN_2;
2829 if (status & 0x20)
2830 report |= SND_JACK_BTN_3;
2831 if (status & 0x80)
2832 report |= SND_JACK_BTN_4;
2833 if (status & 0x100)
2834 report |= SND_JACK_BTN_5;
2835 3023
2836done: 3024done:
2837 snd_soc_jack_report(wm8994->micdet[0].jack, 3025 snd_soc_jack_report(wm8994->micdet[0].jack, report,
2838 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | 3026 SND_JACK_BTN_0 | SND_JACK_MICROPHONE);
2839 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 |
2840 SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT,
2841 report);
2842} 3027}
2843 3028
2844/** 3029/**
@@ -2937,6 +3122,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2937 wm8994->pdata = dev_get_platdata(codec->dev->parent); 3122 wm8994->pdata = dev_get_platdata(codec->dev->parent);
2938 wm8994->codec = codec; 3123 wm8994->codec = codec;
2939 3124
3125 if (wm8994->pdata && wm8994->pdata->micdet_irq)
3126 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
3127 else if (wm8994->pdata && wm8994->pdata->irq_base)
3128 wm8994->micdet_irq = wm8994->pdata->irq_base +
3129 WM8994_IRQ_MIC1_DET;
3130
2940 pm_runtime_enable(codec->dev); 3131 pm_runtime_enable(codec->dev);
2941 pm_runtime_resume(codec->dev); 3132 pm_runtime_resume(codec->dev);
2942 3133
@@ -2985,14 +3176,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2985 3176
2986 switch (control->type) { 3177 switch (control->type) {
2987 case WM8994: 3178 case WM8994:
2988 ret = wm8994_request_irq(codec->control_data, 3179 if (wm8994->micdet_irq) {
2989 WM8994_IRQ_MIC1_DET, 3180 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
2990 wm8994_mic_irq, "Mic 1 detect", 3181 wm8994_mic_irq,
2991 wm8994); 3182 IRQF_TRIGGER_RISING,
2992 if (ret != 0) 3183 "Mic1 detect",
2993 dev_warn(codec->dev, 3184 wm8994);
2994 "Failed to request Mic1 detect IRQ: %d\n", 3185 if (ret != 0)
2995 ret); 3186 dev_warn(codec->dev,
3187 "Failed to request Mic1 detect IRQ: %d\n",
3188 ret);
3189 }
2996 3190
2997 ret = wm8994_request_irq(codec->control_data, 3191 ret = wm8994_request_irq(codec->control_data,
2998 WM8994_IRQ_MIC1_SHRT, 3192 WM8994_IRQ_MIC1_SHRT,
@@ -3023,15 +3217,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3023 break; 3217 break;
3024 3218
3025 case WM8958: 3219 case WM8958:
3026 ret = wm8994_request_irq(codec->control_data, 3220 if (wm8994->micdet_irq) {
3027 WM8994_IRQ_MIC1_DET, 3221 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3028 wm8958_mic_irq, "Mic detect", 3222 wm8958_mic_irq,
3029 wm8994); 3223 IRQF_TRIGGER_RISING,
3030 if (ret != 0) 3224 "Mic detect",
3031 dev_warn(codec->dev, 3225 wm8994);
3032 "Failed to request Mic detect IRQ: %d\n", 3226 if (ret != 0)
3033 ret); 3227 dev_warn(codec->dev,
3034 break; 3228 "Failed to request Mic detect IRQ: %d\n",
3229 ret);
3230 }
3035 } 3231 }
3036 3232
3037 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3233 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
@@ -3112,10 +3308,31 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3112 case WM8994: 3308 case WM8994:
3113 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, 3309 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
3114 ARRAY_SIZE(wm8994_specific_dapm_widgets)); 3310 ARRAY_SIZE(wm8994_specific_dapm_widgets));
3311 if (wm8994->revision < 4) {
3312 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3313 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3314 snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
3315 ARRAY_SIZE(wm8994_adc_revd_widgets));
3316 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3317 ARRAY_SIZE(wm8994_dac_revd_widgets));
3318 } else {
3319 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3320 ARRAY_SIZE(wm8994_lateclk_widgets));
3321 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3322 ARRAY_SIZE(wm8994_adc_widgets));
3323 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3324 ARRAY_SIZE(wm8994_dac_widgets));
3325 }
3115 break; 3326 break;
3116 case WM8958: 3327 case WM8958:
3117 snd_soc_add_controls(codec, wm8958_snd_controls, 3328 snd_soc_add_controls(codec, wm8958_snd_controls,
3118 ARRAY_SIZE(wm8958_snd_controls)); 3329 ARRAY_SIZE(wm8958_snd_controls));
3330 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3331 ARRAY_SIZE(wm8994_lateclk_widgets));
3332 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3333 ARRAY_SIZE(wm8994_adc_widgets));
3334 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3335 ARRAY_SIZE(wm8994_dac_widgets));
3119 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3336 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3120 ARRAY_SIZE(wm8958_dapm_widgets)); 3337 ARRAY_SIZE(wm8958_dapm_widgets));
3121 break; 3338 break;
@@ -3129,8 +3346,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3129 case WM8994: 3346 case WM8994:
3130 snd_soc_dapm_add_routes(dapm, wm8994_intercon, 3347 snd_soc_dapm_add_routes(dapm, wm8994_intercon,
3131 ARRAY_SIZE(wm8994_intercon)); 3348 ARRAY_SIZE(wm8994_intercon));
3349
3350 if (wm8994->revision < 4) {
3351 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3352 ARRAY_SIZE(wm8994_revd_intercon));
3353 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3354 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3355 } else {
3356 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3357 ARRAY_SIZE(wm8994_lateclk_intercon));
3358 }
3132 break; 3359 break;
3133 case WM8958: 3360 case WM8958:
3361 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3362 ARRAY_SIZE(wm8994_lateclk_intercon));
3134 snd_soc_dapm_add_routes(dapm, wm8958_intercon, 3363 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3135 ARRAY_SIZE(wm8958_intercon)); 3364 ARRAY_SIZE(wm8958_intercon));
3136 break; 3365 break;
@@ -3142,7 +3371,8 @@ err_irq:
3142 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 3371 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
3143 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 3372 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
3144 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3373 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
3145 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 3374 if (wm8994->micdet_irq)
3375 free_irq(wm8994->micdet_irq, wm8994);
3146err: 3376err:
3147 kfree(wm8994); 3377 kfree(wm8994);
3148 return ret; 3378 return ret;
@@ -3159,8 +3389,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3159 3389
3160 switch (control->type) { 3390 switch (control->type) {
3161 case WM8994: 3391 case WM8994:
3162 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 3392 if (wm8994->micdet_irq)
3163 wm8994); 3393 free_irq(wm8994->micdet_irq, wm8994);
3164 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 3394 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3165 wm8994); 3395 wm8994);
3166 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 3396 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
@@ -3170,8 +3400,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3170 break; 3400 break;
3171 3401
3172 case WM8958: 3402 case WM8958:
3173 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 3403 if (wm8994->micdet_irq)
3174 wm8994); 3404 free_irq(wm8994->micdet_irq, wm8994);
3175 break; 3405 break;
3176 } 3406 }
3177 kfree(wm8994->retune_mobile_texts); 3407 kfree(wm8994->retune_mobile_texts);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0c355bfc88f1..999b8851226b 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -43,6 +43,6 @@ struct wm8994_access_mask {
43}; 43};
44 44
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; 45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; 46extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
47 47
48#endif 48#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 5c224dd917d7..55cdf2982020 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -15,6 +15,7 @@
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h>
18#include <linux/pm.h> 19#include <linux/pm.h>
19#include <linux/i2c.h> 20#include <linux/i2c.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
@@ -166,7 +167,7 @@ struct wm9081_priv {
166 int fll_fref; 167 int fll_fref;
167 int fll_fout; 168 int fll_fout;
168 int tdm_width; 169 int tdm_width;
169 struct wm9081_retune_mobile_config *retune; 170 struct wm9081_pdata pdata;
170}; 171};
171 172
172static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg) 173static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
@@ -388,27 +389,6 @@ SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
388SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), 389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
389}; 390};
390 391
391static int speaker_event(struct snd_soc_dapm_widget *w,
392 struct snd_kcontrol *kcontrol, int event)
393{
394 struct snd_soc_codec *codec = w->codec;
395 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
396
397 switch (event) {
398 case SND_SOC_DAPM_POST_PMU:
399 reg |= WM9081_SPK_ENA;
400 break;
401
402 case SND_SOC_DAPM_PRE_PMD:
403 reg &= ~WM9081_SPK_ENA;
404 break;
405 }
406
407 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
408
409 return 0;
410}
411
412struct _fll_div { 392struct _fll_div {
413 u16 fll_fratio; 393 u16 fll_fratio;
414 u16 fll_outdiv; 394 u16 fll_outdiv;
@@ -746,9 +726,8 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
746 726
747SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), 727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
748 728
749SND_SOC_DAPM_PGA_E("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0, 729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
750 speaker_event, 730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
751 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
752 731
753SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
754SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -761,7 +740,7 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
761}; 740};
762 741
763 742
764static const struct snd_soc_dapm_route audio_paths[] = { 743static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
765 { "DAC", NULL, "CLK_SYS" }, 744 { "DAC", NULL, "CLK_SYS" },
766 { "DAC", NULL, "CLK_DSP" }, 745 { "DAC", NULL, "CLK_DSP" },
767 746
@@ -779,8 +758,10 @@ static const struct snd_soc_dapm_route audio_paths[] = {
779 { "Speaker PGA", NULL, "TOCLK" }, 758 { "Speaker PGA", NULL, "TOCLK" },
780 { "Speaker PGA", NULL, "CLK_SYS" }, 759 { "Speaker PGA", NULL, "CLK_SYS" },
781 760
782 { "SPKN", NULL, "Speaker PGA" }, 761 { "Speaker", NULL, "Speaker PGA" },
783 { "SPKP", NULL, "Speaker PGA" }, 762
763 { "SPKN", NULL, "Speaker" },
764 { "SPKP", NULL, "Speaker" },
784}; 765};
785 766
786static int wm9081_set_bias_level(struct snd_soc_codec *codec, 767static int wm9081_set_bias_level(struct snd_soc_codec *codec,
@@ -1081,21 +1062,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1081 aif4 |= wm9081->bclk / wm9081->fs; 1062 aif4 |= wm9081->bclk / wm9081->fs;
1082 1063
1083 /* Apply a ReTune Mobile configuration if it's in use */ 1064 /* Apply a ReTune Mobile configuration if it's in use */
1084 if (wm9081->retune) { 1065 if (wm9081->pdata.num_retune_configs) {
1085 struct wm9081_retune_mobile_config *retune = wm9081->retune; 1066 struct wm9081_pdata *pdata = &wm9081->pdata;
1086 struct wm9081_retune_mobile_setting *s; 1067 struct wm9081_retune_mobile_setting *s;
1087 int eq1; 1068 int eq1;
1088 1069
1089 best = 0; 1070 best = 0;
1090 best_val = abs(retune->configs[0].rate - wm9081->fs); 1071 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
1091 for (i = 0; i < retune->num_configs; i++) { 1072 for (i = 0; i < pdata->num_retune_configs; i++) {
1092 cur_val = abs(retune->configs[i].rate - wm9081->fs); 1073 cur_val = abs(pdata->retune_configs[i].rate -
1074 wm9081->fs);
1093 if (cur_val < best_val) { 1075 if (cur_val < best_val) {
1094 best_val = cur_val; 1076 best_val = cur_val;
1095 best = i; 1077 best = i;
1096 } 1078 }
1097 } 1079 }
1098 s = &retune->configs[best]; 1080 s = &pdata->retune_configs[best];
1099 1081
1100 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", 1082 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1101 s->name, s->rate); 1083 s->name, s->rate);
@@ -1138,10 +1120,9 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1138 return 0; 1120 return 0;
1139} 1121}
1140 1122
1141static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec,
1142 int clk_id, unsigned int freq, int dir) 1124 int clk_id, unsigned int freq, int dir)
1143{ 1125{
1144 struct snd_soc_codec *codec = codec_dai->codec;
1145 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1146 1127
1147 switch (clk_id) { 1128 switch (clk_id) {
@@ -1206,7 +1187,6 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1206 1187
1207static struct snd_soc_dai_ops wm9081_dai_ops = { 1188static struct snd_soc_dai_ops wm9081_dai_ops = {
1208 .hw_params = wm9081_hw_params, 1189 .hw_params = wm9081_hw_params,
1209 .set_sysclk = wm9081_set_sysclk,
1210 .set_fmt = wm9081_set_dai_fmt, 1190 .set_fmt = wm9081_set_dai_fmt,
1211 .digital_mute = wm9081_digital_mute, 1191 .digital_mute = wm9081_digital_mute,
1212 .set_tdm_slot = wm9081_set_tdm_slot, 1192 .set_tdm_slot = wm9081_set_tdm_slot,
@@ -1230,7 +1210,6 @@ static struct snd_soc_dai_driver wm9081_dai = {
1230static int wm9081_probe(struct snd_soc_codec *codec) 1210static int wm9081_probe(struct snd_soc_codec *codec)
1231{ 1211{
1232 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1212 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1233 struct snd_soc_dapm_context *dapm = &codec->dapm;
1234 int ret; 1213 int ret;
1235 u16 reg; 1214 u16 reg;
1236 1215
@@ -1254,6 +1233,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1254 return ret; 1233 return ret;
1255 } 1234 }
1256 1235
1236 reg = 0;
1237 if (wm9081->pdata.irq_high)
1238 reg |= WM9081_IRQ_POL;
1239 if (!wm9081->pdata.irq_cmos)
1240 reg |= WM9081_IRQ_OP_CTRL;
1241 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1242 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1243
1257 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1244 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1258 1245
1259 /* Enable zero cross by default */ 1246 /* Enable zero cross by default */
@@ -1265,17 +1252,13 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1265 1252
1266 snd_soc_add_controls(codec, wm9081_snd_controls, 1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1267 ARRAY_SIZE(wm9081_snd_controls)); 1254 ARRAY_SIZE(wm9081_snd_controls));
1268 if (!wm9081->retune) { 1255 if (!wm9081->pdata.num_retune_configs) {
1269 dev_dbg(codec->dev, 1256 dev_dbg(codec->dev,
1270 "No ReTune Mobile data, using normal EQ\n"); 1257 "No ReTune Mobile data, using normal EQ\n");
1271 snd_soc_add_controls(codec, wm9081_eq_controls, 1258 snd_soc_add_controls(codec, wm9081_eq_controls,
1272 ARRAY_SIZE(wm9081_eq_controls)); 1259 ARRAY_SIZE(wm9081_eq_controls));
1273 } 1260 }
1274 1261
1275 snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
1276 ARRAY_SIZE(wm9081_dapm_widgets));
1277 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1278
1279 return ret; 1262 return ret;
1280} 1263}
1281 1264
@@ -1319,11 +1302,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1319 .remove = wm9081_remove, 1302 .remove = wm9081_remove,
1320 .suspend = wm9081_suspend, 1303 .suspend = wm9081_suspend,
1321 .resume = wm9081_resume, 1304 .resume = wm9081_resume,
1305
1306 .set_sysclk = wm9081_set_sysclk,
1322 .set_bias_level = wm9081_set_bias_level, 1307 .set_bias_level = wm9081_set_bias_level,
1308
1323 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), 1309 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
1324 .reg_word_size = sizeof(u16), 1310 .reg_word_size = sizeof(u16),
1325 .reg_cache_default = wm9081_reg_defaults, 1311 .reg_cache_default = wm9081_reg_defaults,
1326 .volatile_register = wm9081_volatile_register, 1312 .volatile_register = wm9081_volatile_register,
1313
1314 .dapm_widgets = wm9081_dapm_widgets,
1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1316 .dapm_routes = wm9081_audio_paths,
1317 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
1327}; 1318};
1328 1319
1329#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1320#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1341,6 +1332,10 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1341 wm9081->control_type = SND_SOC_I2C; 1332 wm9081->control_type = SND_SOC_I2C;
1342 wm9081->control_data = i2c; 1333 wm9081->control_data = i2c;
1343 1334
1335 if (dev_get_platdata(&i2c->dev))
1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1337 sizeof(wm9081->pdata));
1338
1344 ret = snd_soc_register_codec(&i2c->dev, 1339 ret = snd_soc_register_codec(&i2c->dev,
1345 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1340 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1346 if (ret < 0) 1341 if (ret < 0)
@@ -1363,7 +1358,7 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1363 1358
1364static struct i2c_driver wm9081_i2c_driver = { 1359static struct i2c_driver wm9081_i2c_driver = {
1365 .driver = { 1360 .driver = {
1366 .name = "wm9081-codec", 1361 .name = "wm9081",
1367 .owner = THIS_MODULE, 1362 .owner = THIS_MODULE,
1368 }, 1363 },
1369 .probe = wm9081_i2c_probe, 1364 .probe = wm9081_i2c_probe,
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 613df5db0b32..7b6b3c18e299 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -82,7 +82,8 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
82 } while (reg & op && count < 400); 82 } while (reg & op && count < 400);
83 83
84 if (reg & op) 84 if (reg & op)
85 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 85 dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
86 op);
86} 87}
87 88
88/* 89/*
@@ -674,6 +675,9 @@ SND_SOC_DAPM_OUTPUT("LINEOUT2N"),
674}; 675};
675 676
676static const struct snd_soc_dapm_route analogue_routes[] = { 677static const struct snd_soc_dapm_route analogue_routes[] = {
678 { "MICBIAS1", NULL, "CLK_SYS" },
679 { "MICBIAS2", NULL, "CLK_SYS" },
680
677 { "IN1L PGA", "IN1LP Switch", "IN1LP" }, 681 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
678 { "IN1L PGA", "IN1LN Switch", "IN1LN" }, 682 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
679 683
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index b36f0b39b090..fe7984221eb9 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -218,7 +218,19 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
218 .ops = &evm_spdif_ops, 218 .ops = &evm_spdif_ops,
219 }, 219 },
220}; 220};
221static struct snd_soc_dai_link da8xx_evm_dai = { 221
222static struct snd_soc_dai_link da830_evm_dai = {
223 .name = "TLV320AIC3X",
224 .stream_name = "AIC3X",
225 .cpu_dai_name = "davinci-mcasp.1",
226 .codec_dai_name = "tlv320aic3x-hifi",
227 .codec_name = "tlv320aic3x-codec.1-0018",
228 .platform_name = "davinci-pcm-audio",
229 .init = evm_aic3x_init,
230 .ops = &evm_ops,
231};
232
233static struct snd_soc_dai_link da850_evm_dai = {
222 .name = "TLV320AIC3X", 234 .name = "TLV320AIC3X",
223 .stream_name = "AIC3X", 235 .stream_name = "AIC3X",
224 .cpu_dai_name= "davinci-mcasp.0", 236 .cpu_dai_name= "davinci-mcasp.0",
@@ -259,13 +271,13 @@ static struct snd_soc_card dm6467_snd_soc_card_evm = {
259 271
260static struct snd_soc_card da830_snd_soc_card = { 272static struct snd_soc_card da830_snd_soc_card = {
261 .name = "DA830/OMAP-L137 EVM", 273 .name = "DA830/OMAP-L137 EVM",
262 .dai_link = &da8xx_evm_dai, 274 .dai_link = &da830_evm_dai,
263 .num_links = 1, 275 .num_links = 1,
264}; 276};
265 277
266static struct snd_soc_card da850_snd_soc_card = { 278static struct snd_soc_card da850_snd_soc_card = {
267 .name = "DA850/OMAP-L138 EVM", 279 .name = "DA850/OMAP-L138 EVM",
268 .dai_link = &da8xx_evm_dai, 280 .dai_link = &da850_evm_dai,
269 .num_links = 1, 281 .num_links = 1,
270}; 282};
271 283
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 9e0e565e6ed9..d0d60b8a54d4 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -658,7 +658,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
658 return -ENODEV; 658 return -ENODEV;
659 } 659 }
660 660
661 ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, 661 ioarea = request_mem_region(mem->start, resource_size(mem),
662 pdev->name); 662 pdev->name);
663 if (!ioarea) { 663 if (!ioarea) {
664 dev_err(&pdev->dev, "McBSP region already claimed\n"); 664 dev_err(&pdev->dev, "McBSP region already claimed\n");
@@ -694,20 +694,25 @@ static int davinci_i2s_probe(struct platform_device *pdev)
694 } 694 }
695 clk_enable(dev->clk); 695 clk_enable(dev->clk);
696 696
697 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 697 dev->base = ioremap(mem->start, resource_size(mem));
698 if (!dev->base) {
699 dev_err(&pdev->dev, "ioremap failed\n");
700 ret = -ENOMEM;
701 goto err_release_clk;
702 }
698 703
699 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = 704 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
700 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 705 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
701 706
702 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 707 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
703 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 708 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
704 709
705 /* first TX, then RX */ 710 /* first TX, then RX */
706 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 711 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
707 if (!res) { 712 if (!res) {
708 dev_err(&pdev->dev, "no DMA resource\n"); 713 dev_err(&pdev->dev, "no DMA resource\n");
709 ret = -ENXIO; 714 ret = -ENXIO;
710 goto err_free_mem; 715 goto err_iounmap;
711 } 716 }
712 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; 717 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
713 718
@@ -715,7 +720,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
715 if (!res) { 720 if (!res) {
716 dev_err(&pdev->dev, "no DMA resource\n"); 721 dev_err(&pdev->dev, "no DMA resource\n");
717 ret = -ENXIO; 722 ret = -ENXIO;
718 goto err_free_mem; 723 goto err_iounmap;
719 } 724 }
720 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 725 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
721 dev->dev = &pdev->dev; 726 dev->dev = &pdev->dev;
@@ -724,14 +729,19 @@ static int davinci_i2s_probe(struct platform_device *pdev)
724 729
725 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); 730 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
726 if (ret != 0) 731 if (ret != 0)
727 goto err_free_mem; 732 goto err_iounmap;
728 733
729 return 0; 734 return 0;
730 735
736err_iounmap:
737 iounmap(dev->base);
738err_release_clk:
739 clk_disable(dev->clk);
740 clk_put(dev->clk);
731err_free_mem: 741err_free_mem:
732 kfree(dev); 742 kfree(dev);
733err_release_region: 743err_release_region:
734 release_mem_region(mem->start, (mem->end - mem->start) + 1); 744 release_mem_region(mem->start, resource_size(mem));
735 745
736 return ret; 746 return ret;
737} 747}
@@ -747,7 +757,7 @@ static int davinci_i2s_remove(struct platform_device *pdev)
747 dev->clk = NULL; 757 dev->clk = NULL;
748 kfree(dev); 758 kfree(dev);
749 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 759 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
750 release_mem_region(mem->start, (mem->end - mem->start) + 1); 760 release_mem_region(mem->start, resource_size(mem));
751 761
752 return 0; 762 return 0;
753} 763}
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index fb55d2c5d704..a5af834c8ef5 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -868,7 +868,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
868 } 868 }
869 869
870 ioarea = request_mem_region(mem->start, 870 ioarea = request_mem_region(mem->start,
871 (mem->end - mem->start) + 1, pdev->name); 871 resource_size(mem), pdev->name);
872 if (!ioarea) { 872 if (!ioarea) {
873 dev_err(&pdev->dev, "Audio region already claimed\n"); 873 dev_err(&pdev->dev, "Audio region already claimed\n");
874 ret = -EBUSY; 874 ret = -EBUSY;
@@ -885,7 +885,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
885 clk_enable(dev->clk); 885 clk_enable(dev->clk);
886 dev->clk_active = 1; 886 dev->clk_active = 1;
887 887
888 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 888 dev->base = ioremap(mem->start, resource_size(mem));
889 if (!dev->base) {
890 dev_err(&pdev->dev, "ioremap failed\n");
891 ret = -ENOMEM;
892 goto err_release_clk;
893 }
894
889 dev->op_mode = pdata->op_mode; 895 dev->op_mode = pdata->op_mode;
890 dev->tdm_slots = pdata->tdm_slots; 896 dev->tdm_slots = pdata->tdm_slots;
891 dev->num_serializer = pdata->num_serializer; 897 dev->num_serializer = pdata->num_serializer;
@@ -899,14 +905,14 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
899 dma_data->asp_chan_q = pdata->asp_chan_q; 905 dma_data->asp_chan_q = pdata->asp_chan_q;
900 dma_data->ram_chan_q = pdata->ram_chan_q; 906 dma_data->ram_chan_q = pdata->ram_chan_q;
901 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 907 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
902 io_v2p(dev->base)); 908 mem->start);
903 909
904 /* first TX, then RX */ 910 /* first TX, then RX */
905 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 911 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
906 if (!res) { 912 if (!res) {
907 dev_err(&pdev->dev, "no DMA resource\n"); 913 dev_err(&pdev->dev, "no DMA resource\n");
908 ret = -ENODEV; 914 ret = -ENODEV;
909 goto err_release_region; 915 goto err_iounmap;
910 } 916 }
911 917
912 dma_data->channel = res->start; 918 dma_data->channel = res->start;
@@ -915,13 +921,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
915 dma_data->asp_chan_q = pdata->asp_chan_q; 921 dma_data->asp_chan_q = pdata->asp_chan_q;
916 dma_data->ram_chan_q = pdata->ram_chan_q; 922 dma_data->ram_chan_q = pdata->ram_chan_q;
917 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 923 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
918 io_v2p(dev->base)); 924 mem->start);
919 925
920 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 926 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
921 if (!res) { 927 if (!res) {
922 dev_err(&pdev->dev, "no DMA resource\n"); 928 dev_err(&pdev->dev, "no DMA resource\n");
923 ret = -ENODEV; 929 ret = -ENODEV;
924 goto err_release_region; 930 goto err_iounmap;
925 } 931 }
926 932
927 dma_data->channel = res->start; 933 dma_data->channel = res->start;
@@ -929,11 +935,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
929 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); 935 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);
930 936
931 if (ret != 0) 937 if (ret != 0)
932 goto err_release_region; 938 goto err_iounmap;
933 return 0; 939 return 0;
934 940
941err_iounmap:
942 iounmap(dev->base);
943err_release_clk:
944 clk_disable(dev->clk);
945 clk_put(dev->clk);
935err_release_region: 946err_release_region:
936 release_mem_region(mem->start, (mem->end - mem->start) + 1); 947 release_mem_region(mem->start, resource_size(mem));
937err_release_data: 948err_release_data:
938 kfree(dev); 949 kfree(dev);
939 950
@@ -951,7 +962,7 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
951 dev->clk = NULL; 962 dev->clk = NULL;
952 963
953 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 964 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
954 release_mem_region(mem->start, (mem->end - mem->start) + 1); 965 release_mem_region(mem->start, resource_size(mem));
955 966
956 kfree(dev); 967 kfree(dev);
957 968
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index b270085227f3..d3aa15119d26 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -41,17 +41,17 @@ static int edb93xx_hw_params(struct snd_pcm_substream *substream,
41 struct snd_soc_dai *codec_dai = rtd->codec_dai; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 int err; 43 int err;
44 unsigned int mclk_rate;
44 unsigned int rate = params_rate(params); 45 unsigned int rate = params_rate(params);
46
45 /* 47 /*
46 * We set LRCLK equal to `rate' and SCLK = LRCLK * 64, 48 * According to CS4271 datasheet we use MCLK/LRCK=256 for
47 * because our sample size is 32 bit * 2 channels. 49 * rates below 50kHz and 128 for higher sample rates
48 * I2S standard permits us to transmit more bits than
49 * the codec uses.
50 * MCLK = SCLK * 4 is the best recommended value,
51 * but we have to fall back to ratio 2 for higher
52 * sample rates.
53 */ 50 */
54 unsigned int mclk_rate = rate * 64 * ((rate <= 48000) ? 4 : 2); 51 if (rate < 50000)
52 mclk_rate = rate * 64 * 4;
53 else
54 mclk_rate = rate * 64 * 2;
55 55
56 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 56 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_IF | 57 SND_SOC_DAIFMT_NB_IF |
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 68a0bae1208a..104e95cda0ad 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -253,7 +253,6 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
253 struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); 253 struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
254 unsigned v = 0; 254 unsigned v = 0;
255 255
256
257 switch (cmd) { 256 switch (cmd) {
258 case SNDRV_PCM_TRIGGER_START: 257 case SNDRV_PCM_TRIGGER_START:
259 case SNDRV_PCM_TRIGGER_RESUME: 258 case SNDRV_PCM_TRIGGER_RESUME:
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index fff579a1c134..042f4e93746f 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -242,7 +242,7 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
242{ 242{
243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
244 unsigned word_len, div, sdiv, lrdiv; 244 unsigned word_len, div, sdiv, lrdiv;
245 int found = 0, err; 245 int err;
246 246
247 switch (params_format(params)) { 247 switch (params_format(params)) {
248 case SNDRV_PCM_FORMAT_S16_LE: 248 case SNDRV_PCM_FORMAT_S16_LE:
@@ -275,15 +275,14 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
275 * the codec uses. 275 * the codec uses.
276 */ 276 */
277 div = clk_get_rate(info->mclk) / params_rate(params); 277 div = clk_get_rate(info->mclk) / params_rate(params);
278 for (sdiv = 2; sdiv <= 4; sdiv += 2) 278 sdiv = 4;
279 for (lrdiv = 64; lrdiv <= 128; lrdiv <<= 1) 279 if (div > (256 + 512) / 2) {
280 if (sdiv * lrdiv == div) { 280 lrdiv = 128;
281 found = 1; 281 } else {
282 goto out; 282 lrdiv = 64;
283 } 283 if (div < (128 + 256) / 2)
284out: 284 sdiv = 2;
285 if (!found) 285 }
286 return -EINVAL;
287 286
288 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv); 287 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);
289 if (err) 288 if (err)
@@ -314,10 +313,12 @@ static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
314 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 313 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
315 314
316 if (!dai->active) 315 if (!dai->active)
317 return; 316 return 0;
318 317
319 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK); 318 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
320 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE); 319 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
320
321 return 0;
321} 322}
322 323
323static int ep93xx_i2s_resume(struct snd_soc_dai *dai) 324static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
@@ -325,10 +326,12 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
325 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 326 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
326 327
327 if (!dai->active) 328 if (!dai->active)
328 return; 329 return 0;
329 330
330 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK); 331 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
331 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE); 332 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
333
334 return 0;
332} 335}
333#else 336#else
334#define ep93xx_i2s_suspend NULL 337#define ep93xx_i2s_suspend NULL
@@ -352,13 +355,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
352 .playback = { 355 .playback = {
353 .channels_min = 2, 356 .channels_min = 2,
354 .channels_max = 2, 357 .channels_max = 2,
355 .rates = SNDRV_PCM_RATE_8000_96000, 358 .rates = SNDRV_PCM_RATE_8000_192000,
356 .formats = EP93XX_I2S_FORMATS, 359 .formats = EP93XX_I2S_FORMATS,
357 }, 360 },
358 .capture = { 361 .capture = {
359 .channels_min = 2, 362 .channels_min = 2,
360 .channels_max = 2, 363 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_96000, 364 .rates = SNDRV_PCM_RATE_8000_192000,
362 .formats = EP93XX_I2S_FORMATS, 365 .formats = EP93XX_I2S_FORMATS,
363 }, 366 },
364 .ops = &ep93xx_i2s_dai_ops, 367 .ops = &ep93xx_i2s_dai_ops,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 06670776f649..a456e491155f 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
35 SNDRV_PCM_INFO_INTERLEAVED | 35 SNDRV_PCM_INFO_INTERLEAVED |
36 SNDRV_PCM_INFO_BLOCK_TRANSFER), 36 SNDRV_PCM_INFO_BLOCK_TRANSFER),
37 37
38 .rates = SNDRV_PCM_RATE_8000_96000, 38 .rates = SNDRV_PCM_RATE_8000_192000,
39 .rate_min = SNDRV_PCM_RATE_8000, 39 .rate_min = SNDRV_PCM_RATE_8000,
40 .rate_max = SNDRV_PCM_RATE_96000, 40 .rate_max = SNDRV_PCM_RATE_192000,
41 41
42 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 42 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
43 SNDRV_PCM_FMTBIT_S24_LE | 43 SNDRV_PCM_FMTBIT_S24_LE |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 642270a635ea..d8f130d39dd9 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -30,6 +30,16 @@ config SND_MXC_SOC_WM1133_EV1
30 Enable support for audio on the i.MX31ADS with the WM1133-EV1 30 Enable support for audio on the i.MX31ADS with the WM1133-EV1
31 PMIC board with WM8835x fitted. 31 PMIC board with WM8835x fitted.
32 32
33config SND_SOC_MX27VIS_AIC32X4
34 tristate "SoC audio support for Visstrim M10 boards"
35 depends on MACH_IMX27_VISSTRIM_M10
36 select SND_SOC_TVL320AIC32X4
37 select SND_MXC_SOC_SSI
38 select SND_MXC_SOC_MX2
39 help
40 Say Y if you want to add support for SoC audio on Visstrim SM10
41 board with TLV320AIC32X4 codec.
42
33config SND_SOC_PHYCORE_AC97 43config SND_SOC_PHYCORE_AC97
34 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 44 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
35 depends on MACH_PCM043 || MACH_PCA100 45 depends on MACH_PCM043 || MACH_PCA100
@@ -44,7 +54,8 @@ config SND_SOC_EUKREA_TLV320
44 tristate "Eukrea TLV320" 54 tristate "Eukrea TLV320"
45 depends on MACH_EUKREA_MBIMX27_BASEBOARD \ 55 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
46 || MACH_EUKREA_MBIMXSD25_BASEBOARD \ 56 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
47 || MACH_EUKREA_MBIMXSD35_BASEBOARD 57 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
58 || MACH_EUKREA_MBIMXSD51_BASEBOARD
48 select SND_SOC_TLV320AIC23 59 select SND_SOC_TLV320AIC23
49 select SND_MXC_SOC_SSI 60 select SND_MXC_SOC_SSI
50 select SND_MXC_SOC_FIQ 61 select SND_MXC_SOC_FIQ
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index b67fc02a4ecc..d6d609ba7e24 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -10,8 +10,10 @@ obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
12snd-soc-phycore-ac97-objs := phycore-ac97.o 12snd-soc-phycore-ac97-objs := phycore-ac97.o
13snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
13snd-soc-wm1133-ev1-objs := wm1133-ev1.o 14snd-soc-wm1133-ev1-objs := wm1133-ev1.o
14 15
15obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 16obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
16obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 17obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
18obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
17obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 19obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index e20c9e1457c0..75fb4b83548b 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -79,7 +79,7 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = {
79 .name = "tlv320aic23", 79 .name = "tlv320aic23",
80 .stream_name = "TLV320AIC23", 80 .stream_name = "TLV320AIC23",
81 .codec_dai_name = "tlv320aic23-hifi", 81 .codec_dai_name = "tlv320aic23-hifi",
82 .platform_name = "imx-pcm-audio.0", 82 .platform_name = "imx-fiq-pcm-audio.0",
83 .codec_name = "tlv320aic23-codec.0-001a", 83 .codec_name = "tlv320aic23-codec.0-001a",
84 .cpu_dai_name = "imx-ssi.0", 84 .cpu_dai_name = "imx-ssi.0",
85 .ops = &eukrea_tlv320_snd_ops, 85 .ops = &eukrea_tlv320_snd_ops,
@@ -98,7 +98,8 @@ static int __init eukrea_tlv320_init(void)
98 int ret; 98 int ret;
99 99
100 if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd() 100 if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd()
101 && !machine_is_eukrea_cpuimx35sd()) 101 && !machine_is_eukrea_cpuimx35sd()
102 && !machine_is_eukrea_cpuimx51sd())
102 /* return happy. We might run on a totally different machine */ 103 /* return happy. We might run on a totally different machine */
103 return 0; 104 return 0;
104 105
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 30894ea7f333..bc92ec620004 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -108,7 +108,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
108 break; 108 break;
109 case SND_SOC_DAIFMT_DSP_B: 109 case SND_SOC_DAIFMT_DSP_B:
110 /* data on rising edge of bclk, frame high with data */ 110 /* data on rising edge of bclk, frame high with data */
111 strcr |= SSI_STCR_TFSL; 111 strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
112 break; 112 break;
113 case SND_SOC_DAIFMT_DSP_A: 113 case SND_SOC_DAIFMT_DSP_A:
114 /* data on rising edge of bclk, frame high 1clk before data */ 114 /* data on rising edge of bclk, frame high 1clk before data */
@@ -656,6 +656,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
658 658
659 ssi->dma_params_tx.burstsize = 4;
660 ssi->dma_params_rx.burstsize = 4;
661
659 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 662 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
660 if (res) 663 if (res)
661 ssi->dma_params_tx.dma = res->start; 664 ssi->dma_params_tx.dma = res->start;
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
new file mode 100644
index 000000000000..054110b91d42
--- /dev/null
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -0,0 +1,137 @@
1/*
2 * mx27vis-aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/device.h>
27#include <linux/i2c.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <asm/mach-types.h>
33#include <mach/audmux.h>
34
35#include "../codecs/tlv320aic32x4.h"
36#include "imx-ssi.h"
37
38static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret;
45 u32 dai_format;
46
47 dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM;
49
50 /* set codec DAI configuration */
51 snd_soc_dai_set_fmt(codec_dai, dai_format);
52
53 /* set cpu DAI configuration */
54 snd_soc_dai_set_fmt(cpu_dai, dai_format);
55
56 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
57 25000000, SND_SOC_CLOCK_OUT);
58 if (ret) {
59 pr_err("%s: failed setting codec sysclk\n", __func__);
60 return ret;
61 }
62
63 ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
64 SND_SOC_CLOCK_IN);
65 if (ret) {
66 pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
67 return ret;
68 }
69
70 return 0;
71}
72
73static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
74 .hw_params = mx27vis_aic32x4_hw_params,
75};
76
77static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
78 .name = "tlv320aic32x4",
79 .stream_name = "TLV320AIC32X4",
80 .codec_dai_name = "tlv320aic32x4-hifi",
81 .platform_name = "imx-pcm-audio.0",
82 .codec_name = "tlv320aic32x4.0-0018",
83 .cpu_dai_name = "imx-ssi.0",
84 .ops = &mx27vis_aic32x4_snd_ops,
85};
86
87static struct snd_soc_card mx27vis_aic32x4 = {
88 .name = "visstrim_m10-audio",
89 .dai_link = &mx27vis_aic32x4_dai,
90 .num_links = 1,
91};
92
93static struct platform_device *mx27vis_aic32x4_snd_device;
94
95static int __init mx27vis_aic32x4_init(void)
96{
97 int ret;
98
99 mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1);
100 if (!mx27vis_aic32x4_snd_device)
101 return -ENOMEM;
102
103 platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4);
104 ret = platform_device_add(mx27vis_aic32x4_snd_device);
105
106 if (ret) {
107 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
108 platform_device_put(mx27vis_aic32x4_snd_device);
109 }
110
111 /* Connect SSI0 as clock slave to SSI1 external pins */
112 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
113 MXC_AUDMUX_V1_PCR_SYN |
114 MXC_AUDMUX_V1_PCR_TFSDIR |
115 MXC_AUDMUX_V1_PCR_TCLKDIR |
116 MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
117 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
118 );
119 mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
120 MXC_AUDMUX_V1_PCR_SYN |
121 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
122 );
123
124 return ret;
125}
126
127static void __exit mx27vis_aic32x4_exit(void)
128{
129 platform_device_unregister(mx27vis_aic32x4_snd_device);
130}
131
132module_init(mx27vis_aic32x4_init);
133module_exit(mx27vis_aic32x4_exit);
134
135MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
136MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
137MODULE_LICENSE("GPL");
diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig
index 1ad753836356..29350428f1c2 100644
--- a/sound/soc/mid-x86/Kconfig
+++ b/sound/soc/mid-x86/Kconfig
@@ -1,6 +1,7 @@
1config SND_MFLD_MACHINE 1config SND_MFLD_MACHINE
2 tristate "SOC Machine Audio driver for Intel Medfield MID platform" 2 tristate "SOC Machine Audio driver for Intel Medfield MID platform"
3 depends on INTEL_SCU_IPC 3 depends on INTEL_SCU_IPC
4 depends on SND_INTEL_SST
4 select SND_SOC_SN95031 5 select SND_SOC_SN95031
5 select SND_SST_PLATFORM 6 select SND_SST_PLATFORM
6 help 7 help
@@ -11,4 +12,3 @@ config SND_MFLD_MACHINE
11 12
12config SND_SST_PLATFORM 13config SND_SST_PLATFORM
13 tristate 14 tristate
14 depends on SND_INTEL_SST
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 7925851a5de1..429aa1be2cff 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -27,18 +27,59 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/io.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
31#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
32#include <sound/soc.h> 33#include <sound/soc.h>
34#include <sound/jack.h>
33#include "../codecs/sn95031.h" 35#include "../codecs/sn95031.h"
34 36
35#define MID_MONO 1 37#define MID_MONO 1
36#define MID_STEREO 2 38#define MID_STEREO 2
37#define MID_MAX_CAP 5 39#define MID_MAX_CAP 5
40#define MFLD_JACK_INSERT 0x04
41
42enum soc_mic_bias_zones {
43 MFLD_MV_START = 0,
44 /* mic bias volutage range for Headphones*/
45 MFLD_MV_HP = 400,
46 /* mic bias volutage range for American Headset*/
47 MFLD_MV_AM_HS = 650,
48 /* mic bias volutage range for Headset*/
49 MFLD_MV_HS = 2000,
50 MFLD_MV_UNDEFINED,
51};
38 52
39static unsigned int hs_switch; 53static unsigned int hs_switch;
40static unsigned int lo_dac; 54static unsigned int lo_dac;
41 55
56struct mfld_mc_private {
57 struct platform_device *socdev;
58 void __iomem *int_base;
59 struct snd_soc_codec *codec;
60 u8 interrupt_status;
61};
62
63struct snd_soc_jack mfld_jack;
64
65/*Headset jack detection DAPM pins */
66static struct snd_soc_jack_pin mfld_jack_pins[] = {
67 {
68 .pin = "Headphones",
69 .mask = SND_JACK_HEADPHONE,
70 },
71 {
72 .pin = "AMIC1",
73 .mask = SND_JACK_MICROPHONE,
74 },
75};
76
77/* jack detection voltage zones */
78static struct snd_soc_jack_zone mfld_zones[] = {
79 {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE},
80 {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET},
81};
82
42/* sound card controls */ 83/* sound card controls */
43static const char *headset_switch_text[] = {"Earpiece", "Headset"}; 84static const char *headset_switch_text[] = {"Earpiece", "Headset"};
44 85
@@ -67,13 +108,11 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
67 108
68 if (ucontrol->value.integer.value[0]) { 109 if (ucontrol->value.integer.value[0]) {
69 pr_debug("hs_set HS path\n"); 110 pr_debug("hs_set HS path\n");
70 snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTL"); 111 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
71 snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTR");
72 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 112 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
73 } else { 113 } else {
74 pr_debug("hs_set EP path\n"); 114 pr_debug("hs_set EP path\n");
75 snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL"); 115 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
76 snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR");
77 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 116 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
78 } 117 }
79 snd_soc_dapm_sync(&codec->dapm); 118 snd_soc_dapm_sync(&codec->dapm);
@@ -91,12 +130,10 @@ static void lo_enable_out_pins(struct snd_soc_codec *codec)
91 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT"); 130 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT");
92 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT"); 131 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT");
93 if (hs_switch) { 132 if (hs_switch) {
94 snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTL"); 133 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
95 snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTR");
96 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 134 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
97 } else { 135 } else {
98 snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL"); 136 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
99 snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR");
100 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); 137 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
101 } 138 }
102} 139}
@@ -130,8 +167,7 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
130 167
131 case 1: 168 case 1:
132 pr_debug("set hs path\n"); 169 pr_debug("set hs path\n");
133 snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL"); 170 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
134 snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR");
135 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); 171 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
136 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); 172 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22);
137 break; 173 break;
@@ -162,12 +198,45 @@ static const struct snd_kcontrol_new mfld_snd_controls[] = {
162 lo_get_switch, lo_set_switch), 198 lo_get_switch, lo_set_switch),
163}; 199};
164 200
201static const struct snd_soc_dapm_widget mfld_widgets[] = {
202 SND_SOC_DAPM_HP("Headphones", NULL),
203 SND_SOC_DAPM_MIC("Mic", NULL),
204};
205
206static const struct snd_soc_dapm_route mfld_map[] = {
207 {"Headphones", NULL, "HPOUTR"},
208 {"Headphones", NULL, "HPOUTL"},
209 {"Mic", NULL, "AMIC1"},
210};
211
212static void mfld_jack_check(unsigned int intr_status)
213{
214 struct mfld_jack_data jack_data;
215
216 jack_data.mfld_jack = &mfld_jack;
217 jack_data.intr_id = intr_status;
218
219 sn95031_jack_detection(&jack_data);
220 /* TODO: add american headset detection post gpiolib support */
221}
222
165static int mfld_init(struct snd_soc_pcm_runtime *runtime) 223static int mfld_init(struct snd_soc_pcm_runtime *runtime)
166{ 224{
167 struct snd_soc_codec *codec = runtime->codec; 225 struct snd_soc_codec *codec = runtime->codec;
168 struct snd_soc_dapm_context *dapm = &codec->dapm; 226 struct snd_soc_dapm_context *dapm = &codec->dapm;
169 int ret_val; 227 int ret_val;
170 228
229 /* Add jack sense widgets */
230 snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets));
231
232 /* Set up the map */
233 snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map));
234
235 /* always connected */
236 snd_soc_dapm_enable_pin(dapm, "Headphones");
237 snd_soc_dapm_enable_pin(dapm, "Mic");
238 snd_soc_dapm_sync(dapm);
239
171 ret_val = snd_soc_add_controls(codec, mfld_snd_controls, 240 ret_val = snd_soc_add_controls(codec, mfld_snd_controls,
172 ARRAY_SIZE(mfld_snd_controls)); 241 ARRAY_SIZE(mfld_snd_controls));
173 if (ret_val) { 242 if (ret_val) {
@@ -175,8 +244,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
175 return ret_val; 244 return ret_val;
176 } 245 }
177 /* default is earpiece pin, userspace sets it explcitly */ 246 /* default is earpiece pin, userspace sets it explcitly */
178 snd_soc_dapm_disable_pin(dapm, "HPOUTL"); 247 snd_soc_dapm_disable_pin(dapm, "Headphones");
179 snd_soc_dapm_disable_pin(dapm, "HPOUTR");
180 /* default is lineout NC, userspace sets it explcitly */ 248 /* default is lineout NC, userspace sets it explcitly */
181 snd_soc_dapm_disable_pin(dapm, "LINEOUTL"); 249 snd_soc_dapm_disable_pin(dapm, "LINEOUTL");
182 snd_soc_dapm_disable_pin(dapm, "LINEOUTR"); 250 snd_soc_dapm_disable_pin(dapm, "LINEOUTR");
@@ -185,7 +253,35 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
185 /* we dont use linein in this so set to NC */ 253 /* we dont use linein in this so set to NC */
186 snd_soc_dapm_disable_pin(dapm, "LINEINL"); 254 snd_soc_dapm_disable_pin(dapm, "LINEINL");
187 snd_soc_dapm_disable_pin(dapm, "LINEINR"); 255 snd_soc_dapm_disable_pin(dapm, "LINEINR");
188 return snd_soc_dapm_sync(dapm); 256 snd_soc_dapm_sync(dapm);
257
258 /* Headset and button jack detection */
259 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
260 SND_JACK_HEADSET | SND_JACK_BTN_0 |
261 SND_JACK_BTN_1, &mfld_jack);
262 if (ret_val) {
263 pr_err("jack creation failed\n");
264 return ret_val;
265 }
266
267 ret_val = snd_soc_jack_add_pins(&mfld_jack,
268 ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins);
269 if (ret_val) {
270 pr_err("adding jack pins failed\n");
271 return ret_val;
272 }
273 ret_val = snd_soc_jack_add_zones(&mfld_jack,
274 ARRAY_SIZE(mfld_zones), mfld_zones);
275 if (ret_val) {
276 pr_err("adding jack zones failed\n");
277 return ret_val;
278 }
279
280 /* we want to check if anything is inserted at boot,
281 * so send a fake event to codec and it will read adc
282 * to find if anything is there or not */
283 mfld_jack_check(MFLD_JACK_INSERT);
284 return ret_val;
189} 285}
190 286
191struct snd_soc_dai_link mfld_msic_dailink[] = { 287struct snd_soc_dai_link mfld_msic_dailink[] = {
@@ -234,37 +330,94 @@ static struct snd_soc_card snd_soc_card_mfld = {
234 .num_links = ARRAY_SIZE(mfld_msic_dailink), 330 .num_links = ARRAY_SIZE(mfld_msic_dailink),
235}; 331};
236 332
333static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)
334{
335 struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev;
336
337 memcpy_fromio(&mc_private->interrupt_status,
338 ((void *)(mc_private->int_base)),
339 sizeof(u8));
340 return IRQ_WAKE_THREAD;
341}
342
343static irqreturn_t snd_mfld_jack_detection(int irq, void *data)
344{
345 struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data;
346
347 if (mfld_jack.codec == NULL)
348 return IRQ_HANDLED;
349 mfld_jack_check(mc_drv_ctx->interrupt_status);
350
351 return IRQ_HANDLED;
352}
353
237static int __devinit snd_mfld_mc_probe(struct platform_device *pdev) 354static int __devinit snd_mfld_mc_probe(struct platform_device *pdev)
238{ 355{
239 struct platform_device *socdev; 356 int ret_val = 0, irq;
240 int ret_val = 0; 357 struct mfld_mc_private *mc_drv_ctx;
358 struct resource *irq_mem;
241 359
242 pr_debug("snd_mfld_mc_probe called\n"); 360 pr_debug("snd_mfld_mc_probe called\n");
243 361
244 socdev = platform_device_alloc("soc-audio", -1); 362 /* retrive the irq number */
245 if (!socdev) { 363 irq = platform_get_irq(pdev, 0);
246 pr_err("soc-audio device allocation failed\n"); 364
365 /* audio interrupt base of SRAM location where
366 * interrupts are stored by System FW */
367 mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC);
368 if (!mc_drv_ctx) {
369 pr_err("allocation failed\n");
247 return -ENOMEM; 370 return -ENOMEM;
248 } 371 }
249 platform_set_drvdata(socdev, &snd_soc_card_mfld); 372
250 ret_val = platform_device_add(socdev); 373 irq_mem = platform_get_resource_byname(
374 pdev, IORESOURCE_MEM, "IRQ_BASE");
375 if (!irq_mem) {
376 pr_err("no mem resource given\n");
377 ret_val = -ENODEV;
378 goto unalloc;
379 }
380 mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start,
381 resource_size(irq_mem));
382 if (!mc_drv_ctx->int_base) {
383 pr_err("Mapping of cache failed\n");
384 ret_val = -ENOMEM;
385 goto unalloc;
386 }
387 /* register for interrupt */
388 ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler,
389 snd_mfld_jack_detection,
390 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
251 if (ret_val) { 391 if (ret_val) {
252 pr_err("Unable to add soc-audio device, err %d\n", ret_val); 392 pr_err("cannot register IRQ\n");
253 platform_device_put(socdev); 393 goto unalloc;
254 } 394 }
255 395 /* register the soc card */
256 platform_set_drvdata(pdev, socdev); 396 snd_soc_card_mfld.dev = &pdev->dev;
257 397 ret_val = snd_soc_register_card(&snd_soc_card_mfld);
398 if (ret_val) {
399 pr_debug("snd_soc_register_card failed %d\n", ret_val);
400 goto freeirq;
401 }
402 platform_set_drvdata(pdev, mc_drv_ctx);
258 pr_debug("successfully exited probe\n"); 403 pr_debug("successfully exited probe\n");
259 return ret_val; 404 return ret_val;
405
406freeirq:
407 free_irq(irq, mc_drv_ctx);
408unalloc:
409 kfree(mc_drv_ctx);
410 return ret_val;
260} 411}
261 412
262static int __devexit snd_mfld_mc_remove(struct platform_device *pdev) 413static int __devexit snd_mfld_mc_remove(struct platform_device *pdev)
263{ 414{
264 struct platform_device *socdev = platform_get_drvdata(pdev); 415 struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
265 pr_debug("snd_mfld_mc_remove called\n");
266 416
267 platform_device_unregister(socdev); 417 pr_debug("snd_mfld_mc_remove called\n");
418 free_irq(platform_get_irq(pdev, 0), mc_drv_ctx);
419 snd_soc_unregister_card(&snd_soc_card_mfld);
420 kfree(mc_drv_ctx);
268 platform_set_drvdata(pdev, NULL); 421 platform_set_drvdata(pdev, NULL);
269 return 0; 422 return 0;
270} 423}
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 96e6e9c9c5f4..ee2c22475a76 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -365,6 +365,14 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
365 return stream->stream_info.buffer_ptr; 365 return stream->stream_info.buffer_ptr;
366} 366}
367 367
368static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params)
370{
371 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
372 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
373
374 return 0;
375}
368 376
369static struct snd_pcm_ops sst_platform_ops = { 377static struct snd_pcm_ops sst_platform_ops = {
370 .open = sst_platform_open, 378 .open = sst_platform_open,
@@ -373,6 +381,7 @@ static struct snd_pcm_ops sst_platform_ops = {
373 .prepare = sst_platform_pcm_prepare, 381 .prepare = sst_platform_pcm_prepare,
374 .trigger = sst_platform_pcm_trigger, 382 .trigger = sst_platform_pcm_trigger,
375 .pointer = sst_platform_pcm_pointer, 383 .pointer = sst_platform_pcm_pointer,
384 .hw_params = sst_platform_pcm_hw_params,
376}; 385};
377 386
378static void sst_pcm_free(struct snd_pcm *pcm) 387static void sst_pcm_free(struct snd_pcm *pcm)
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 28333e7d9c50..dc65650a6fa1 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -117,7 +117,7 @@ static struct snd_soc_dai_link e740_dai[] = {
117 { 117 {
118 .name = "AC97", 118 .name = "AC97",
119 .stream_name = "AC97 HiFi", 119 .stream_name = "AC97 HiFi",
120 .cpu_dai_name = "pxa-ac97.0", 120 .cpu_dai_name = "pxa2xx-ac97",
121 .codec_dai_name = "wm9705-hifi", 121 .codec_dai_name = "wm9705-hifi",
122 .platform_name = "pxa-pcm-audio", 122 .platform_name = "pxa-pcm-audio",
123 .codec_name = "wm9705-codec", 123 .codec_name = "wm9705-codec",
@@ -126,7 +126,7 @@ static struct snd_soc_dai_link e740_dai[] = {
126 { 126 {
127 .name = "AC97 Aux", 127 .name = "AC97 Aux",
128 .stream_name = "AC97 Aux", 128 .stream_name = "AC97 Aux",
129 .cpu_dai_name = "pxa-ac97.1", 129 .cpu_dai_name = "pxa2xx-ac97-aux",
130 .codec_dai_name = "wm9705-aux", 130 .codec_dai_name = "wm9705-aux",
131 .platform_name = "pxa-pcm-audio", 131 .platform_name = "pxa-pcm-audio",
132 .codec_name = "wm9705-codec", 132 .codec_name = "wm9705-codec",
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 01bf31675c55..51897fcd911b 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -99,7 +99,7 @@ static struct snd_soc_dai_link e750_dai[] = {
99 { 99 {
100 .name = "AC97", 100 .name = "AC97",
101 .stream_name = "AC97 HiFi", 101 .stream_name = "AC97 HiFi",
102 .cpu_dai_name = "pxa-ac97.0", 102 .cpu_dai_name = "pxa2xx-ac97",
103 .codec_dai_name = "wm9705-hifi", 103 .codec_dai_name = "wm9705-hifi",
104 .platform_name = "pxa-pcm-audio", 104 .platform_name = "pxa-pcm-audio",
105 .codec_name = "wm9705-codec", 105 .codec_name = "wm9705-codec",
@@ -109,7 +109,7 @@ static struct snd_soc_dai_link e750_dai[] = {
109 { 109 {
110 .name = "AC97 Aux", 110 .name = "AC97 Aux",
111 .stream_name = "AC97 Aux", 111 .stream_name = "AC97 Aux",
112 .cpu_dai_name = "pxa-ac97.1", 112 .cpu_dai_name = "pxa2xx-ac97-aux",
113 .codec_dai_name ="wm9705-aux", 113 .codec_dai_name ="wm9705-aux",
114 .platform_name = "pxa-pcm-audio", 114 .platform_name = "pxa-pcm-audio",
115 .codec_name = "wm9705-codec", 115 .codec_name = "wm9705-codec",
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index c6a37c6ef23b..053ed208e59f 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -89,7 +89,7 @@ static struct snd_soc_dai_link e800_dai[] = {
89 { 89 {
90 .name = "AC97", 90 .name = "AC97",
91 .stream_name = "AC97 HiFi", 91 .stream_name = "AC97 HiFi",
92 .cpu_dai_name = "pxa-ac97.0", 92 .cpu_dai_name = "pxa2xx-ac97",
93 .codec_dai_name = "wm9712-hifi", 93 .codec_dai_name = "wm9712-hifi",
94 .platform_name = "pxa-pcm-audio", 94 .platform_name = "pxa-pcm-audio",
95 .codec_name = "wm9712-codec", 95 .codec_name = "wm9712-codec",
@@ -98,7 +98,7 @@ static struct snd_soc_dai_link e800_dai[] = {
98 { 98 {
99 .name = "AC97 Aux", 99 .name = "AC97 Aux",
100 .stream_name = "AC97 Aux", 100 .stream_name = "AC97 Aux",
101 .cpu_dai_name = "pxa-ac97.1", 101 .cpu_dai_name = "pxa2xx-ac97-aux",
102 .codec_dai_name ="wm9712-aux", 102 .codec_dai_name ="wm9712-aux",
103 .platform_name = "pxa-pcm-audio", 103 .platform_name = "pxa-pcm-audio",
104 .codec_name = "wm9712-codec", 104 .codec_name = "wm9712-codec",
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index fc22e6eefc98..b13a4252812d 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -37,7 +37,7 @@ static struct snd_soc_dai_link em_x270_dai[] = {
37 { 37 {
38 .name = "AC97", 38 .name = "AC97",
39 .stream_name = "AC97 HiFi", 39 .stream_name = "AC97 HiFi",
40 .cpu_dai_name = "pxa-ac97.0", 40 .cpu_dai_name = "pxa2xx-ac97",
41 .codec_dai_name = "wm9712-hifi", 41 .codec_dai_name = "wm9712-hifi",
42 .platform_name = "pxa-pcm-audio", 42 .platform_name = "pxa-pcm-audio",
43 .codec_name = "wm9712-codec", 43 .codec_name = "wm9712-codec",
@@ -45,7 +45,7 @@ static struct snd_soc_dai_link em_x270_dai[] = {
45 { 45 {
46 .name = "AC97 Aux", 46 .name = "AC97 Aux",
47 .stream_name = "AC97 Aux", 47 .stream_name = "AC97 Aux",
48 .cpu_dai_name = "pxa-ac97.1", 48 .cpu_dai_name = "pxa2xx-ac97-aux",
49 .codec_dai_name ="wm9712-aux", 49 .codec_dai_name ="wm9712-aux",
50 .platform_name = "pxa-pcm-audio", 50 .platform_name = "pxa-pcm-audio",
51 .codec_name = "wm9712-codec", 51 .codec_name = "wm9712-codec",
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 0d70fc8c12bd..38ca6759907e 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -162,7 +162,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
162 { 162 {
163 .name = "AC97", 163 .name = "AC97",
164 .stream_name = "AC97 HiFi", 164 .stream_name = "AC97 HiFi",
165 .cpu_dai_name = "pxa-ac97.0", 165 .cpu_dai_name = "pxa2xx-ac97",
166 .codec_dai_name = "wm9713-hifi", 166 .codec_dai_name = "wm9713-hifi",
167 .codec_name = "wm9713-codec", 167 .codec_name = "wm9713-codec",
168 .init = mioa701_wm9713_init, 168 .init = mioa701_wm9713_init,
@@ -172,7 +172,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
172 { 172 {
173 .name = "AC97 Aux", 173 .name = "AC97 Aux",
174 .stream_name = "AC97 Aux", 174 .stream_name = "AC97 Aux",
175 .cpu_dai_name = "pxa-ac97.1", 175 .cpu_dai_name = "pxa2xx-ac97-aux",
176 .codec_dai_name ="wm9713-aux", 176 .codec_dai_name ="wm9713-aux",
177 .codec_name = "wm9713-codec", 177 .codec_name = "wm9713-codec",
178 .platform_name = "pxa-pcm-audio", 178 .platform_name = "pxa-pcm-audio",
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 857db96d4a4f..504e4004f004 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -132,7 +132,7 @@ static struct snd_soc_dai_link palm27x_dai[] = {
132{ 132{
133 .name = "AC97 HiFi", 133 .name = "AC97 HiFi",
134 .stream_name = "AC97 HiFi", 134 .stream_name = "AC97 HiFi",
135 .cpu_dai_name = "pxa-ac97.0", 135 .cpu_dai_name = "pxa2xx-ac97",
136 .codec_dai_name = "wm9712-hifi", 136 .codec_dai_name = "wm9712-hifi",
137 .codec_name = "wm9712-codec", 137 .codec_name = "wm9712-codec",
138 .platform_name = "pxa-pcm-audio", 138 .platform_name = "pxa-pcm-audio",
@@ -141,7 +141,7 @@ static struct snd_soc_dai_link palm27x_dai[] = {
141{ 141{
142 .name = "AC97 Aux", 142 .name = "AC97 Aux",
143 .stream_name = "AC97 Aux", 143 .stream_name = "AC97 Aux",
144 .cpu_dai_name = "pxa-ac97.1", 144 .cpu_dai_name = "pxa2xx-ac97-aux",
145 .codec_dai_name = "wm9712-aux", 145 .codec_dai_name = "wm9712-aux",
146 .codec_name = "wm9712-codec", 146 .codec_name = "wm9712-codec",
147 .platform_name = "pxa-pcm-audio", 147 .platform_name = "pxa-pcm-audio",
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index db1dd560a585..2afabaf59491 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -229,19 +229,19 @@ static struct snd_soc_dai_link raumfeld_dai[] = {
229{ 229{
230 .name = "ak4104", 230 .name = "ak4104",
231 .stream_name = "Playback", 231 .stream_name = "Playback",
232 .cpu_dai_name = "pxa-ssp-dai.1", 232 .cpu_dai_name = "pxa-ssp-dai.1",
233 .codec_dai_name = "ak4104-hifi", 233 .codec_dai_name = "ak4104-hifi",
234 .platform_name = "pxa-pcm-audio", 234 .platform_name = "pxa-pcm-audio",
235 .ops = &raumfeld_ak4104_ops, 235 .ops = &raumfeld_ak4104_ops,
236 .codec_name = "ak4104-codec.0", 236 .codec_name = "ak4104-codec.0",
237}, 237},
238{ 238{
239 .name = "CS4270", 239 .name = "CS4270",
240 .stream_name = "CS4270", 240 .stream_name = "CS4270",
241 .cpu_dai_name = "pxa-ssp-dai.0", 241 .cpu_dai_name = "pxa-ssp-dai.0",
242 .platform_name = "pxa-pcm-audio", 242 .platform_name = "pxa-pcm-audio",
243 .codec_dai_name = "cs4270-hifi", 243 .codec_dai_name = "cs4270-hifi",
244 .codec_name = "cs4270-codec.0-0048", 244 .codec_name = "cs4270-codec.0-0048",
245 .ops = &raumfeld_cs4270_ops, 245 .ops = &raumfeld_cs4270_ops,
246},}; 246},};
247 247
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 489139a31cf9..9a2351366957 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -219,7 +219,7 @@ static struct snd_soc_dai_link tosa_dai[] = {
219{ 219{
220 .name = "AC97", 220 .name = "AC97",
221 .stream_name = "AC97 HiFi", 221 .stream_name = "AC97 HiFi",
222 .cpu_dai_name = "pxa-ac97.0", 222 .cpu_dai_name = "pxa2xx-ac97",
223 .codec_dai_name = "wm9712-hifi", 223 .codec_dai_name = "wm9712-hifi",
224 .platform_name = "pxa-pcm-audio", 224 .platform_name = "pxa-pcm-audio",
225 .codec_name = "wm9712-codec", 225 .codec_name = "wm9712-codec",
@@ -229,7 +229,7 @@ static struct snd_soc_dai_link tosa_dai[] = {
229{ 229{
230 .name = "AC97 Aux", 230 .name = "AC97 Aux",
231 .stream_name = "AC97 Aux", 231 .stream_name = "AC97 Aux",
232 .cpu_dai_name = "pxa-ac97.1", 232 .cpu_dai_name = "pxa2xx-ac97-aux",
233 .codec_dai_name = "wm9712-aux", 233 .codec_dai_name = "wm9712-aux",
234 .platform_name = "pxa-pcm-audio", 234 .platform_name = "pxa-pcm-audio",
235 .codec_name = "wm9712-codec", 235 .codec_name = "wm9712-codec",
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 3ceaef68e01d..d69d9fc32233 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -95,6 +95,11 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
95 .pin = "Headphone Jack", 95 .pin = "Headphone Jack",
96 .mask = SND_JACK_HEADPHONE, 96 .mask = SND_JACK_HEADPHONE,
97 }, 97 },
98 {
99 .pin = "Ext Spk",
100 .mask = SND_JACK_HEADPHONE,
101 .invert = 1
102 },
98}; 103};
99 104
100/* Headset jack detection gpios */ 105/* Headset jack detection gpios */
@@ -147,7 +152,7 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
147 snd_soc_dapm_disable_pin(dapm, "LINPUT3"); 152 snd_soc_dapm_disable_pin(dapm, "LINPUT3");
148 snd_soc_dapm_disable_pin(dapm, "RINPUT3"); 153 snd_soc_dapm_disable_pin(dapm, "RINPUT3");
149 snd_soc_dapm_disable_pin(dapm, "OUT3"); 154 snd_soc_dapm_disable_pin(dapm, "OUT3");
150 snd_soc_dapm_disable_pin(dapm, "MONO"); 155 snd_soc_dapm_disable_pin(dapm, "MONO1");
151 156
152 /* Add z2 specific widgets */ 157 /* Add z2 specific widgets */
153 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, 158 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index c5858296b48a..ac577263b3e3 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -166,7 +166,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
166 .stream_name = "AC97 HiFi", 166 .stream_name = "AC97 HiFi",
167 .codec_name = "wm9713-codec", 167 .codec_name = "wm9713-codec",
168 .platform_name = "pxa-pcm-audio", 168 .platform_name = "pxa-pcm-audio",
169 .cpu_dai_name = "pxa-ac97.0", 169 .cpu_dai_name = "pxa2xx-ac97",
170 .codec_name = "wm9713-hifi", 170 .codec_name = "wm9713-hifi",
171 .init = zylonite_wm9713_init, 171 .init = zylonite_wm9713_init,
172}, 172},
@@ -175,7 +175,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
175 .stream_name = "AC97 Aux", 175 .stream_name = "AC97 Aux",
176 .codec_name = "wm9713-codec", 176 .codec_name = "wm9713-codec",
177 .platform_name = "pxa-pcm-audio", 177 .platform_name = "pxa-pcm-audio",
178 .cpu_dai_name = "pxa-ac97.1", 178 .cpu_dai_name = "pxa2xx-ac97-aux",
179 .codec_name = "wm9713-aux", 179 .codec_name = "wm9713-aux",
180}, 180},
181{ 181{
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index a6a6b5fa2f2f..a08237acc53b 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -35,23 +35,16 @@ config SND_SAMSUNG_I2S
35 tristate 35 tristate
36 36
37config SND_SOC_SAMSUNG_NEO1973_WM8753 37config SND_SOC_SAMSUNG_NEO1973_WM8753
38 tristate "SoC I2S Audio support for NEO1973 - WM8753" 38 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)"
39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA01 39 depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02)
40 select SND_S3C24XX_I2S 40 select SND_S3C24XX_I2S
41 select SND_SOC_WM8753 41 select SND_SOC_WM8753
42 select SND_SOC_LM4857 if MACH_NEO1973_GTA01
43 select SND_SOC_DFBMCS320
42 help 44 help
43 Say Y if you want to add support for SoC audio on smdk2440 45 Say Y here to enable audio support for the Openmoko Neo1973
44 with the WM8753. 46 Smartphones.
45 47
46config SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753
47 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
48 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
49 select SND_S3C24XX_I2S
50 select SND_SOC_WM8753
51 help
52 This driver provides audio support for the Openmoko Neo FreeRunner
53 smartphone.
54
55config SND_SOC_SAMSUNG_JIVE_WM8750 48config SND_SOC_SAMSUNG_JIVE_WM8750
56 tristate "SoC I2S Audio support for Jive" 49 tristate "SoC I2S Audio support for Jive"
57 depends on SND_SOC_SAMSUNG && MACH_JIVE 50 depends on SND_SOC_SAMSUNG && MACH_JIVE
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 705d4e8a6724..294dec05c26d 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
20# S3C24XX Machine Support 20# S3C24XX Machine Support
21snd-soc-jive-wm8750-objs := jive_wm8750.o 21snd-soc-jive-wm8750-objs := jive_wm8750.o
22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
23snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
24snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 23snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
25snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 24snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
26snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o 25snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
@@ -38,7 +37,6 @@ snd-soc-smdk-spdif-objs := smdk_spdif.o
38 37
39obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
40obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
42obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
43obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 41obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
44obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o 42obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 9bce1df1f0d1..5cb3b880f0d5 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -310,7 +310,7 @@ dma_pointer(struct snd_pcm_substream *substream)
310 /* we seem to be getting the odd error from the pcm library due 310 /* we seem to be getting the odd error from the pcm library due
311 * to out-of-bounds pointers. this is maybe due to the dma engine 311 * to out-of-bounds pointers. this is maybe due to the dma engine
312 * not having loaded the new values for the channel before being 312 * not having loaded the new values for the channel before being
313 * callled... (todo - fix ) 313 * called... (todo - fix )
314 */ 314 */
315 315
316 if (res >= snd_pcm_lib_buffer_bytes(substream)) { 316 if (res >= snd_pcm_lib_buffer_bytes(substream)) {
diff --git a/sound/soc/samsung/lm4857.h b/sound/soc/samsung/lm4857.h
deleted file mode 100644
index 0cf5b7011d6f..000000000000
--- a/sound/soc/samsung/lm4857.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * lm4857.h -- ALSA Soc Audio Layer
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 18th Jun 2007 Initial version.
15 */
16
17#ifndef LM4857_H_
18#define LM4857_H_
19
20/* The register offsets in the cache array */
21#define LM4857_MVOL 0
22#define LM4857_LVOL 1
23#define LM4857_RVOL 2
24#define LM4857_CTRL 3
25
26/* the shifts required to set these bits */
27#define LM4857_3D 5
28#define LM4857_WAKEUP 5
29#define LM4857_EPGAIN 4
30
31#endif /*LM4857_H_*/
32
diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
deleted file mode 100644
index 95ebf812b146..000000000000
--- a/sound/soc/samsung/neo1973_gta02_wm8753.c
+++ /dev/null
@@ -1,494 +0,0 @@
1/*
2 * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02)
3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
6 * Copyright 2007 Wolfson Microelectronics PLC.
7 * Author: Graeme Gregory <linux@wolfsonmicro.com>
8 * Copyright 2009 Wolfson Microelectronics
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/gpio.h>
17
18#include <sound/soc.h>
19
20#include <asm/mach-types.h>
21#include <plat/regs-iis.h>
22#include <mach/gta02.h>
23
24#include "../codecs/wm8753.h"
25#include "s3c24xx-i2s.h"
26
27static struct snd_soc_card neo1973_gta02;
28
29static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
30 struct snd_pcm_hw_params *params)
31{
32 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_soc_dai *codec_dai = rtd->codec_dai;
34 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
35 unsigned int pll_out = 0, bclk = 0;
36 int ret = 0;
37 unsigned long iis_clkrate;
38
39 iis_clkrate = s3c24xx_i2s_get_clockrate();
40
41 switch (params_rate(params)) {
42 case 8000:
43 case 16000:
44 pll_out = 12288000;
45 break;
46 case 48000:
47 bclk = WM8753_BCLK_DIV_4;
48 pll_out = 12288000;
49 break;
50 case 96000:
51 bclk = WM8753_BCLK_DIV_2;
52 pll_out = 12288000;
53 break;
54 case 11025:
55 bclk = WM8753_BCLK_DIV_16;
56 pll_out = 11289600;
57 break;
58 case 22050:
59 bclk = WM8753_BCLK_DIV_8;
60 pll_out = 11289600;
61 break;
62 case 44100:
63 bclk = WM8753_BCLK_DIV_4;
64 pll_out = 11289600;
65 break;
66 case 88200:
67 bclk = WM8753_BCLK_DIV_2;
68 pll_out = 11289600;
69 break;
70 }
71
72 /* set codec DAI configuration */
73 ret = snd_soc_dai_set_fmt(codec_dai,
74 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
75 SND_SOC_DAIFMT_CBM_CFM);
76 if (ret < 0)
77 return ret;
78
79 /* set cpu DAI configuration */
80 ret = snd_soc_dai_set_fmt(cpu_dai,
81 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
82 SND_SOC_DAIFMT_CBM_CFM);
83 if (ret < 0)
84 return ret;
85
86 /* set the codec system clock for DAC and ADC */
87 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
88 SND_SOC_CLOCK_IN);
89 if (ret < 0)
90 return ret;
91
92 /* set MCLK division for sample rate */
93 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
94 S3C2410_IISMOD_32FS);
95 if (ret < 0)
96 return ret;
97
98 /* set codec BCLK division for sample rate */
99 ret = snd_soc_dai_set_clkdiv(codec_dai,
100 WM8753_BCLKDIV, bclk);
101 if (ret < 0)
102 return ret;
103
104 /* set prescaler division for sample rate */
105 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
106 S3C24XX_PRESCALE(4, 4));
107 if (ret < 0)
108 return ret;
109
110 /* codec PLL input is PCLK/4 */
111 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
112 iis_clkrate / 4, pll_out);
113 if (ret < 0)
114 return ret;
115
116 return 0;
117}
118
119static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
120{
121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
122 struct snd_soc_dai *codec_dai = rtd->codec_dai;
123
124 /* disable the PLL */
125 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
126}
127
128/*
129 * Neo1973 WM8753 HiFi DAI opserations.
130 */
131static struct snd_soc_ops neo1973_gta02_hifi_ops = {
132 .hw_params = neo1973_gta02_hifi_hw_params,
133 .hw_free = neo1973_gta02_hifi_hw_free,
134};
135
136static int neo1973_gta02_voice_hw_params(
137 struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params)
139{
140 struct snd_soc_pcm_runtime *rtd = substream->private_data;
141 struct snd_soc_dai *codec_dai = rtd->codec_dai;
142 unsigned int pcmdiv = 0;
143 int ret = 0;
144 unsigned long iis_clkrate;
145
146 iis_clkrate = s3c24xx_i2s_get_clockrate();
147
148 if (params_rate(params) != 8000)
149 return -EINVAL;
150 if (params_channels(params) != 1)
151 return -EINVAL;
152
153 pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
154
155 /* todo: gg check mode (DSP_B) against CSR datasheet */
156 /* set codec DAI configuration */
157 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
158 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
159 if (ret < 0)
160 return ret;
161
162 /* set the codec system clock for DAC and ADC */
163 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK,
164 12288000, SND_SOC_CLOCK_IN);
165 if (ret < 0)
166 return ret;
167
168 /* set codec PCM division for sample rate */
169 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV,
170 pcmdiv);
171 if (ret < 0)
172 return ret;
173
174 /* configure and enable PLL for 12.288MHz output */
175 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
176 iis_clkrate / 4, 12288000);
177 if (ret < 0)
178 return ret;
179
180 return 0;
181}
182
183static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
184{
185 struct snd_soc_pcm_runtime *rtd = substream->private_data;
186 struct snd_soc_dai *codec_dai = rtd->codec_dai;
187
188 /* disable the PLL */
189 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
190}
191
192static struct snd_soc_ops neo1973_gta02_voice_ops = {
193 .hw_params = neo1973_gta02_voice_hw_params,
194 .hw_free = neo1973_gta02_voice_hw_free,
195};
196
197#define LM4853_AMP 1
198#define LM4853_SPK 2
199
200static u8 lm4853_state;
201
202/* This has no effect, it exists only to maintain compatibility with
203 * existing ALSA state files.
204 */
205static int lm4853_set_state(struct snd_kcontrol *kcontrol,
206 struct snd_ctl_elem_value *ucontrol)
207{
208 int val = ucontrol->value.integer.value[0];
209
210 if (val)
211 lm4853_state |= LM4853_AMP;
212 else
213 lm4853_state &= ~LM4853_AMP;
214
215 return 0;
216}
217
218static int lm4853_get_state(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_value *ucontrol)
220{
221 ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP;
222
223 return 0;
224}
225
226static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_value *ucontrol)
228{
229 int val = ucontrol->value.integer.value[0];
230
231 if (val) {
232 lm4853_state |= LM4853_SPK;
233 gpio_set_value(GTA02_GPIO_HP_IN, 0);
234 } else {
235 lm4853_state &= ~LM4853_SPK;
236 gpio_set_value(GTA02_GPIO_HP_IN, 1);
237 }
238
239 return 0;
240}
241
242static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
243 struct snd_ctl_elem_value *ucontrol)
244{
245 ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1;
246
247 return 0;
248}
249
250static int lm4853_event(struct snd_soc_dapm_widget *w,
251 struct snd_kcontrol *k,
252 int event)
253{
254 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
255
256 return 0;
257}
258
259static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
260 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
261 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
262 SND_SOC_DAPM_LINE("GSM Line In", NULL),
263 SND_SOC_DAPM_MIC("Headset Mic", NULL),
264 SND_SOC_DAPM_MIC("Handset Mic", NULL),
265 SND_SOC_DAPM_SPK("Handset Spk", NULL),
266};
267
268
269/* example machine audio_mapnections */
270static const struct snd_soc_dapm_route audio_map[] = {
271
272 /* Connections to the lm4853 amp */
273 {"Stereo Out", NULL, "LOUT1"},
274 {"Stereo Out", NULL, "ROUT1"},
275
276 /* Connections to the GSM Module */
277 {"GSM Line Out", NULL, "MONO1"},
278 {"GSM Line Out", NULL, "MONO2"},
279 {"RXP", NULL, "GSM Line In"},
280 {"RXN", NULL, "GSM Line In"},
281
282 /* Connections to Headset */
283 {"MIC1", NULL, "Mic Bias"},
284 {"Mic Bias", NULL, "Headset Mic"},
285
286 /* Call Mic */
287 {"MIC2", NULL, "Mic Bias"},
288 {"MIC2N", NULL, "Mic Bias"},
289 {"Mic Bias", NULL, "Handset Mic"},
290
291 /* Call Speaker */
292 {"Handset Spk", NULL, "LOUT2"},
293 {"Handset Spk", NULL, "ROUT2"},
294
295 /* Connect the ALC pins */
296 {"ACIN", NULL, "ACOP"},
297};
298
299static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
300 SOC_DAPM_PIN_SWITCH("Stereo Out"),
301 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
302 SOC_DAPM_PIN_SWITCH("GSM Line In"),
303 SOC_DAPM_PIN_SWITCH("Headset Mic"),
304 SOC_DAPM_PIN_SWITCH("Handset Mic"),
305 SOC_DAPM_PIN_SWITCH("Handset Spk"),
306
307 /* This has no effect, it exists only to maintain compatibility with
308 * existing ALSA state files.
309 */
310 SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0,
311 lm4853_get_state,
312 lm4853_set_state),
313 SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0,
314 lm4853_get_spk,
315 lm4853_set_spk),
316};
317
318/*
319 * This is an example machine initialisation for a wm8753 connected to a
320 * neo1973 GTA02.
321 */
322static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
323{
324 struct snd_soc_codec *codec = rtd->codec;
325 struct snd_soc_dapm_context *dapm = &codec->dapm;
326 int err;
327
328 /* set up NC codec pins */
329 snd_soc_dapm_nc_pin(dapm, "OUT3");
330 snd_soc_dapm_nc_pin(dapm, "OUT4");
331 snd_soc_dapm_nc_pin(dapm, "LINE1");
332 snd_soc_dapm_nc_pin(dapm, "LINE2");
333
334 /* Add neo1973 gta02 specific widgets */
335 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
336 ARRAY_SIZE(wm8753_dapm_widgets));
337
338 /* add neo1973 gta02 specific controls */
339 err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls,
340 ARRAY_SIZE(wm8753_neo1973_gta02_controls));
341
342 if (err < 0)
343 return err;
344
345 /* set up neo1973 gta02 specific audio path audio_map */
346 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
347
348 /* set endpoints to default off mode */
349 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
350 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
351 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
352 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
353 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
354 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
355
356 /* allow audio paths from the GSM modem to run during suspend */
357 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
358 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
359 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
360 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
361 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
362 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
363
364 snd_soc_dapm_sync(dapm);
365
366 return 0;
367}
368
369/*
370 * BT Codec DAI
371 */
372static struct snd_soc_dai_driver bt_dai = {
373 .name = "bluetooth-dai",
374 .playback = {
375 .channels_min = 1,
376 .channels_max = 1,
377 .rates = SNDRV_PCM_RATE_8000,
378 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
379 .capture = {
380 .channels_min = 1,
381 .channels_max = 1,
382 .rates = SNDRV_PCM_RATE_8000,
383 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
384};
385
386static struct snd_soc_dai_link neo1973_gta02_dai[] = {
387{ /* Hifi Playback - for similatious use with voice below */
388 .name = "WM8753",
389 .stream_name = "WM8753 HiFi",
390 .cpu_dai_name = "s3c24xx-iis",
391 .codec_dai_name = "wm8753-hifi",
392 .init = neo1973_gta02_wm8753_init,
393 .platform_name = "samsung-audio",
394 .codec_name = "wm8753-codec.0-001a",
395 .ops = &neo1973_gta02_hifi_ops,
396},
397{ /* Voice via BT */
398 .name = "Bluetooth",
399 .stream_name = "Voice",
400 .cpu_dai_name = "bluetooth-dai",
401 .codec_dai_name = "wm8753-voice",
402 .ops = &neo1973_gta02_voice_ops,
403 .codec_name = "wm8753-codec.0-001a",
404 .platform_name = "samsung-audio",
405},
406};
407
408static struct snd_soc_card neo1973_gta02 = {
409 .name = "neo1973-gta02",
410 .dai_link = neo1973_gta02_dai,
411 .num_links = ARRAY_SIZE(neo1973_gta02_dai),
412};
413
414static struct platform_device *neo1973_gta02_snd_device;
415
416static int __init neo1973_gta02_init(void)
417{
418 int ret;
419
420 if (!machine_is_neo1973_gta02()) {
421 printk(KERN_INFO
422 "Only GTA02 is supported by this ASoC driver\n");
423 return -ENODEV;
424 }
425
426 neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1);
427 if (!neo1973_gta02_snd_device)
428 return -ENOMEM;
429
430 /* register bluetooth DAI here */
431 ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai);
432 if (ret)
433 goto err_put_device;
434
435 platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
436 ret = platform_device_add(neo1973_gta02_snd_device);
437
438 if (ret)
439 goto err_unregister_dai;
440
441 /* Initialise GPIOs used by amp */
442 ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
443 if (ret) {
444 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
445 goto err_del_device;
446 }
447
448 ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
449 if (ret) {
450 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN);
451 goto err_free_gpio_hp_in;
452 }
453
454 ret = gpio_request(GTA02_GPIO_AMP_SHUT, "GTA02_AMP_SHUT");
455 if (ret) {
456 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_AMP_SHUT);
457 goto err_free_gpio_hp_in;
458 }
459
460 ret = gpio_direction_output(GTA02_GPIO_AMP_SHUT, 1);
461 if (ret) {
462 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_AMP_SHUT);
463 goto err_free_gpio_amp_shut;
464 }
465
466 return 0;
467
468err_free_gpio_amp_shut:
469 gpio_free(GTA02_GPIO_AMP_SHUT);
470err_free_gpio_hp_in:
471 gpio_free(GTA02_GPIO_HP_IN);
472err_del_device:
473 platform_device_del(neo1973_gta02_snd_device);
474err_unregister_dai:
475 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
476err_put_device:
477 platform_device_put(neo1973_gta02_snd_device);
478 return ret;
479}
480module_init(neo1973_gta02_init);
481
482static void __exit neo1973_gta02_exit(void)
483{
484 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
485 platform_device_unregister(neo1973_gta02_snd_device);
486 gpio_free(GTA02_GPIO_HP_IN);
487 gpio_free(GTA02_GPIO_AMP_SHUT);
488}
489module_exit(neo1973_gta02_exit);
490
491/* Module information */
492MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org");
493MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02");
494MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index d3cd6888a810..78bfdb3f5d7e 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -1,56 +1,32 @@
1/* 1/*
2 * neo1973_wm8753.c -- SoC audio for Neo1973 2 * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices
3 * 3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
4 * Copyright 2007 Wolfson Microelectronics PLC. 6 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 7 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 8 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
9 * Copyright 2009 Wolfson Microelectronics
7 * 10 *
8 * This program is free software; you can redistribute it and/or modify it 11 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 12 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 13 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 14 * option) any later version.
12 *
13 */ 15 */
14 16
15#include <linux/module.h> 17#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
20#include <linux/i2c.h> 19#include <linux/gpio.h>
21#include <sound/core.h> 20
22#include <sound/pcm.h>
23#include <sound/soc.h> 21#include <sound/soc.h>
24#include <sound/tlv.h>
25 22
26#include <asm/mach-types.h> 23#include <asm/mach-types.h>
27#include <mach/regs-clock.h>
28#include <mach/regs-gpio.h>
29#include <mach/hardware.h>
30#include <linux/io.h>
31#include <mach/spi-gpio.h>
32
33#include <plat/regs-iis.h> 24#include <plat/regs-iis.h>
25#include <mach/gta02.h>
34 26
35#include "../codecs/wm8753.h" 27#include "../codecs/wm8753.h"
36#include "lm4857.h"
37#include "dma.h"
38#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
39 29
40/* define the scenarios */
41#define NEO_AUDIO_OFF 0
42#define NEO_GSM_CALL_AUDIO_HANDSET 1
43#define NEO_GSM_CALL_AUDIO_HEADSET 2
44#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3
45#define NEO_STEREO_TO_SPEAKERS 4
46#define NEO_STEREO_TO_HEADPHONES 5
47#define NEO_CAPTURE_HANDSET 6
48#define NEO_CAPTURE_HEADSET 7
49#define NEO_CAPTURE_BLUETOOTH 8
50
51static struct snd_soc_card neo1973;
52static struct i2c_client *i2c;
53
54static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 30static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params) 31 struct snd_pcm_hw_params *params)
56{ 32{
@@ -61,8 +37,6 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
61 int ret = 0; 37 int ret = 0;
62 unsigned long iis_clkrate; 38 unsigned long iis_clkrate;
63 39
64 pr_debug("Entered %s\n", __func__);
65
66 iis_clkrate = s3c24xx_i2s_get_clockrate(); 40 iis_clkrate = s3c24xx_i2s_get_clockrate();
67 41
68 switch (params_rate(params)) { 42 switch (params_rate(params)) {
@@ -147,8 +121,6 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_dai *codec_dai = rtd->codec_dai; 122 struct snd_soc_dai *codec_dai = rtd->codec_dai;
149 123
150 pr_debug("Entered %s\n", __func__);
151
152 /* disable the PLL */ 124 /* disable the PLL */
153 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); 125 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
154} 126}
@@ -170,8 +142,6 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
170 int ret = 0; 142 int ret = 0;
171 unsigned long iis_clkrate; 143 unsigned long iis_clkrate;
172 144
173 pr_debug("Entered %s\n", __func__);
174
175 iis_clkrate = s3c24xx_i2s_get_clockrate(); 145 iis_clkrate = s3c24xx_i2s_get_clockrate();
176 146
177 if (params_rate(params) != 8000) 147 if (params_rate(params) != 8000)
@@ -213,8 +183,6 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
213 struct snd_soc_pcm_runtime *rtd = substream->private_data; 183 struct snd_soc_pcm_runtime *rtd = substream->private_data;
214 struct snd_soc_dai *codec_dai = rtd->codec_dai; 184 struct snd_soc_dai *codec_dai = rtd->codec_dai;
215 185
216 pr_debug("Entered %s\n", __func__);
217
218 /* disable the PLL */ 186 /* disable the PLL */
219 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); 187 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
220} 188}
@@ -224,335 +192,232 @@ static struct snd_soc_ops neo1973_voice_ops = {
224 .hw_free = neo1973_voice_hw_free, 192 .hw_free = neo1973_voice_hw_free,
225}; 193};
226 194
227static int neo1973_scenario; 195/* Shared routes and controls */
228
229static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
230 struct snd_ctl_elem_value *ucontrol)
231{
232 ucontrol->value.integer.value[0] = neo1973_scenario;
233 return 0;
234}
235
236static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
237{
238 struct snd_soc_dapm_context *dapm = &codec->dapm;
239
240 pr_debug("Entered %s\n", __func__);
241
242 switch (neo1973_scenario) {
243 case NEO_AUDIO_OFF:
244 snd_soc_dapm_disable_pin(dapm, "Audio Out");
245 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
246 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
247 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
248 snd_soc_dapm_disable_pin(dapm, "Call Mic");
249 break;
250 case NEO_GSM_CALL_AUDIO_HANDSET:
251 snd_soc_dapm_enable_pin(dapm, "Audio Out");
252 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
253 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
254 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
255 snd_soc_dapm_enable_pin(dapm, "Call Mic");
256 break;
257 case NEO_GSM_CALL_AUDIO_HEADSET:
258 snd_soc_dapm_enable_pin(dapm, "Audio Out");
259 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
260 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
261 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
262 snd_soc_dapm_disable_pin(dapm, "Call Mic");
263 break;
264 case NEO_GSM_CALL_AUDIO_BLUETOOTH:
265 snd_soc_dapm_disable_pin(dapm, "Audio Out");
266 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
267 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
268 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
269 snd_soc_dapm_disable_pin(dapm, "Call Mic");
270 break;
271 case NEO_STEREO_TO_SPEAKERS:
272 snd_soc_dapm_enable_pin(dapm, "Audio Out");
273 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
274 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
275 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
276 snd_soc_dapm_disable_pin(dapm, "Call Mic");
277 break;
278 case NEO_STEREO_TO_HEADPHONES:
279 snd_soc_dapm_enable_pin(dapm, "Audio Out");
280 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
281 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
282 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
283 snd_soc_dapm_disable_pin(dapm, "Call Mic");
284 break;
285 case NEO_CAPTURE_HANDSET:
286 snd_soc_dapm_disable_pin(dapm, "Audio Out");
287 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
288 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
289 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
290 snd_soc_dapm_enable_pin(dapm, "Call Mic");
291 break;
292 case NEO_CAPTURE_HEADSET:
293 snd_soc_dapm_disable_pin(dapm, "Audio Out");
294 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
295 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
296 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
297 snd_soc_dapm_disable_pin(dapm, "Call Mic");
298 break;
299 case NEO_CAPTURE_BLUETOOTH:
300 snd_soc_dapm_disable_pin(dapm, "Audio Out");
301 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
302 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
303 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
304 snd_soc_dapm_disable_pin(dapm, "Call Mic");
305 break;
306 default:
307 snd_soc_dapm_disable_pin(dapm, "Audio Out");
308 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
309 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
310 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
311 snd_soc_dapm_disable_pin(dapm, "Call Mic");
312 }
313 196
314 snd_soc_dapm_sync(dapm); 197static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = {
198 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
199 SND_SOC_DAPM_LINE("GSM Line In", NULL),
200 SND_SOC_DAPM_MIC("Headset Mic", NULL),
201 SND_SOC_DAPM_MIC("Handset Mic", NULL),
202};
315 203
316 return 0; 204static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = {
317} 205 /* Connections to the GSM Module */
206 {"GSM Line Out", NULL, "MONO1"},
207 {"GSM Line Out", NULL, "MONO2"},
208 {"RXP", NULL, "GSM Line In"},
209 {"RXN", NULL, "GSM Line In"},
318 210
319static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, 211 /* Connections to Headset */
320 struct snd_ctl_elem_value *ucontrol) 212 {"MIC1", NULL, "Mic Bias"},
321{ 213 {"Mic Bias", NULL, "Headset Mic"},
322 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
323 214
324 pr_debug("Entered %s\n", __func__); 215 /* Call Mic */
216 {"MIC2", NULL, "Mic Bias"},
217 {"MIC2N", NULL, "Mic Bias"},
218 {"Mic Bias", NULL, "Handset Mic"},
325 219
326 if (neo1973_scenario == ucontrol->value.integer.value[0]) 220 /* Connect the ALC pins */
327 return 0; 221 {"ACIN", NULL, "ACOP"},
222};
328 223
329 neo1973_scenario = ucontrol->value.integer.value[0]; 224static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
330 set_scenario_endpoints(codec, neo1973_scenario); 225 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
331 return 1; 226 SOC_DAPM_PIN_SWITCH("GSM Line In"),
332} 227 SOC_DAPM_PIN_SWITCH("Headset Mic"),
228 SOC_DAPM_PIN_SWITCH("Handset Mic"),
229};
333 230
334static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; 231/* GTA02 specific routes and controlls */
335 232
336static void lm4857_write_regs(void) 233#ifdef CONFIG_MACH_NEO1973_GTA02
337{
338 pr_debug("Entered %s\n", __func__);
339 234
340 if (i2c_master_send(i2c, lm4857_regs, 4) != 4) 235static int gta02_speaker_enabled;
341 printk(KERN_ERR "lm4857: i2c write failed\n");
342}
343 236
344static int lm4857_get_reg(struct snd_kcontrol *kcontrol, 237static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
345 struct snd_ctl_elem_value *ucontrol) 238 struct snd_ctl_elem_value *ucontrol)
346{ 239{
347 struct soc_mixer_control *mc = 240 gta02_speaker_enabled = ucontrol->value.integer.value[0];
348 (struct soc_mixer_control *)kcontrol->private_value;
349 int reg = mc->reg;
350 int shift = mc->shift;
351 int mask = mc->max;
352 241
353 pr_debug("Entered %s\n", __func__); 242 gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled);
354 243
355 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
356 return 0; 244 return 0;
357} 245}
358 246
359static int lm4857_set_reg(struct snd_kcontrol *kcontrol, 247static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
360 struct snd_ctl_elem_value *ucontrol) 248 struct snd_ctl_elem_value *ucontrol)
361{ 249{
362 struct soc_mixer_control *mc = 250 ucontrol->value.integer.value[0] = gta02_speaker_enabled;
363 (struct soc_mixer_control *)kcontrol->private_value; 251 return 0;
364 int reg = mc->reg;
365 int shift = mc->shift;
366 int mask = mc->max;
367
368 if (((lm4857_regs[reg] >> shift) & mask) ==
369 ucontrol->value.integer.value[0])
370 return 0;
371
372 lm4857_regs[reg] &= ~(mask << shift);
373 lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift;
374 lm4857_write_regs();
375 return 1;
376} 252}
377 253
378static int lm4857_get_mode(struct snd_kcontrol *kcontrol, 254static int lm4853_event(struct snd_soc_dapm_widget *w,
379 struct snd_ctl_elem_value *ucontrol) 255 struct snd_kcontrol *k, int event)
380{ 256{
381 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; 257 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
382
383 pr_debug("Entered %s\n", __func__);
384
385 if (value)
386 value -= 5;
387 258
388 ucontrol->value.integer.value[0] = value;
389 return 0; 259 return 0;
390} 260}
391 261
392static int lm4857_set_mode(struct snd_kcontrol *kcontrol, 262static const struct snd_soc_dapm_route neo1973_gta02_routes[] = {
393 struct snd_ctl_elem_value *ucontrol) 263 /* Connections to the amp */
394{ 264 {"Stereo Out", NULL, "LOUT1"},
395 u8 value = ucontrol->value.integer.value[0]; 265 {"Stereo Out", NULL, "ROUT1"},
396
397 pr_debug("Entered %s\n", __func__);
398
399 if (value)
400 value += 5;
401
402 if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value)
403 return 0;
404
405 lm4857_regs[LM4857_CTRL] &= 0xF0;
406 lm4857_regs[LM4857_CTRL] |= value;
407 lm4857_write_regs();
408 return 1;
409}
410 266
411static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { 267 /* Call Speaker */
412 SND_SOC_DAPM_LINE("Audio Out", NULL), 268 {"Handset Spk", NULL, "LOUT2"},
413 SND_SOC_DAPM_LINE("GSM Line Out", NULL), 269 {"Handset Spk", NULL, "ROUT2"},
414 SND_SOC_DAPM_LINE("GSM Line In", NULL),
415 SND_SOC_DAPM_MIC("Headset Mic", NULL),
416 SND_SOC_DAPM_MIC("Call Mic", NULL),
417}; 270};
418 271
272static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = {
273 SOC_DAPM_PIN_SWITCH("Handset Spk"),
274 SOC_DAPM_PIN_SWITCH("Stereo Out"),
419 275
420static const struct snd_soc_dapm_route dapm_routes[] = { 276 SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0,
421 277 lm4853_get_spk,
422 /* Connections to the lm4857 amp */ 278 lm4853_set_spk),
423 {"Audio Out", NULL, "LOUT1"}, 279};
424 {"Audio Out", NULL, "ROUT1"},
425
426 /* Connections to the GSM Module */
427 {"GSM Line Out", NULL, "MONO1"},
428 {"GSM Line Out", NULL, "MONO2"},
429 {"RXP", NULL, "GSM Line In"},
430 {"RXN", NULL, "GSM Line In"},
431 280
432 /* Connections to Headset */ 281static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = {
433 {"MIC1", NULL, "Mic Bias"}, 282 SND_SOC_DAPM_SPK("Handset Spk", NULL),
434 {"Mic Bias", NULL, "Headset Mic"}, 283 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
284};
435 285
436 /* Call Mic */ 286static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
437 {"MIC2", NULL, "Mic Bias"}, 287{
438 {"MIC2N", NULL, "Mic Bias"}, 288 struct snd_soc_dapm_context *dapm = &codec->dapm;
439 {"Mic Bias", NULL, "Call Mic"}, 289 int ret;
440 290
441 /* Connect the ALC pins */ 291 ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets,
442 {"ACIN", NULL, "ACOP"}, 292 ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets));
443}; 293 if (ret)
294 return ret;
444 295
445static const char *lm4857_mode[] = { 296 ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes,
446 "Off", 297 ARRAY_SIZE(neo1973_gta02_routes));
447 "Call Speaker", 298 if (ret)
448 "Stereo Speakers", 299 return ret;
449 "Stereo Speakers + Headphones",
450 "Headphones"
451};
452 300
453static const struct soc_enum lm4857_mode_enum[] = { 301 ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls,
454 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), 302 ARRAY_SIZE(neo1973_gta02_wm8753_controls));
455}; 303 if (ret)
304 return ret;
456 305
457static const char *neo_scenarios[] = { 306 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
458 "Off", 307 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
459 "GSM Handset", 308 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
460 "GSM Headset", 309 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
461 "GSM Bluetooth",
462 "Speakers",
463 "Headphones",
464 "Capture Handset",
465 "Capture Headset",
466 "Capture Bluetooth"
467};
468 310
469static const struct soc_enum neo_scenario_enum[] = { 311 return 0;
470 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios), 312}
471};
472 313
473static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0); 314#else
474static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0); 315static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; }
475 316#endif
476static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
477 SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
478 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
479 SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
480 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
481 SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
482 lm4857_get_reg, lm4857_set_reg, mono_tlv),
483 SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
484 lm4857_get_mode, lm4857_set_mode),
485 SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
486 neo1973_get_scenario, neo1973_set_scenario),
487 SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0,
488 lm4857_get_reg, lm4857_set_reg),
489 SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0,
490 lm4857_get_reg, lm4857_set_reg),
491 SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0,
492 lm4857_get_reg, lm4857_set_reg),
493 SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0,
494 lm4857_get_reg, lm4857_set_reg),
495};
496 317
497/*
498 * This is an example machine initialisation for a wm8753 connected to a
499 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
500 * to re-route the audio in such an event.
501 */
502static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) 318static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
503{ 319{
504 struct snd_soc_codec *codec = rtd->codec; 320 struct snd_soc_codec *codec = rtd->codec;
505 struct snd_soc_dapm_context *dapm = &codec->dapm; 321 struct snd_soc_dapm_context *dapm = &codec->dapm;
506 int err; 322 int ret;
507
508 pr_debug("Entered %s\n", __func__);
509 323
510 /* set up NC codec pins */ 324 /* set up NC codec pins */
511 snd_soc_dapm_nc_pin(dapm, "LOUT2"); 325 if (machine_is_neo1973_gta01()) {
512 snd_soc_dapm_nc_pin(dapm, "ROUT2"); 326 snd_soc_dapm_nc_pin(dapm, "LOUT2");
327 snd_soc_dapm_nc_pin(dapm, "ROUT2");
328 }
513 snd_soc_dapm_nc_pin(dapm, "OUT3"); 329 snd_soc_dapm_nc_pin(dapm, "OUT3");
514 snd_soc_dapm_nc_pin(dapm, "OUT4"); 330 snd_soc_dapm_nc_pin(dapm, "OUT4");
515 snd_soc_dapm_nc_pin(dapm, "LINE1"); 331 snd_soc_dapm_nc_pin(dapm, "LINE1");
516 snd_soc_dapm_nc_pin(dapm, "LINE2"); 332 snd_soc_dapm_nc_pin(dapm, "LINE2");
517 333
518 /* Add neo1973 specific widgets */ 334 /* Add neo1973 specific widgets */
519 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, 335 ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets,
520 ARRAY_SIZE(wm8753_dapm_widgets)); 336 ARRAY_SIZE(neo1973_wm8753_dapm_widgets));
521 337 if (ret)
522 /* set endpoints to default mode */ 338 return ret;
523 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
524 339
525 /* add neo1973 specific controls */ 340 /* add neo1973 specific controls */
526 err = snd_soc_add_controls(codec, wm8753_neo1973_controls, 341 ret = snd_soc_add_controls(codec, neo1973_wm8753_controls,
527 ARRAY_SIZE(8753_neo1973_controls)); 342 ARRAY_SIZE(neo1973_wm8753_controls));
528 if (err < 0) 343 if (ret)
529 return err; 344 return ret;
530 345
531 /* set up neo1973 specific audio routes */ 346 /* set up neo1973 specific audio routes */
532 err = snd_soc_dapm_add_routes(dapm, dapm_routes, 347 ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes,
533 ARRAY_SIZE(dapm_routes)); 348 ARRAY_SIZE(neo1973_wm8753_routes));
349 if (ret)
350 return ret;
351
352 /* set endpoints to default off mode */
353 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
354 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
355 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
356 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
357
358 /* allow audio paths from the GSM modem to run during suspend */
359 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
360 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
361 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
362 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
363
364 if (machine_is_neo1973_gta02()) {
365 ret = neo1973_gta02_wm8753_init(codec);
366 if (ret)
367 return ret;
368 }
534 369
535 snd_soc_dapm_sync(dapm); 370 snd_soc_dapm_sync(dapm);
371
536 return 0; 372 return 0;
537} 373}
538 374
539/* 375/* GTA01 specific controlls */
540 * BT Codec DAI 376
541 */ 377#ifdef CONFIG_MACH_NEO1973_GTA01
542static struct snd_soc_dai bt_dai = { 378
543 .name = "bluetooth-dai", 379static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = {
544 .playback = { 380 {"Amp IN", NULL, "ROUT1"},
545 .channels_min = 1, 381 {"Amp IN", NULL, "LOUT1"},
546 .channels_max = 1, 382
547 .rates = SNDRV_PCM_RATE_8000, 383 {"Handset Spk", NULL, "Amp EP"},
548 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 384 {"Stereo Out", NULL, "Amp LS"},
549 .capture = { 385 {"Headphone", NULL, "Amp HP"},
550 .channels_min = 1, 386};
551 .channels_max = 1, 387
552 .rates = SNDRV_PCM_RATE_8000, 388static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = {
553 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 389 SND_SOC_DAPM_SPK("Handset Spk", NULL),
390 SND_SOC_DAPM_SPK("Stereo Out", NULL),
391 SND_SOC_DAPM_HP("Headphone", NULL),
554}; 392};
555 393
394static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
395{
396 int ret;
397
398 ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets,
399 ARRAY_SIZE(neo1973_lm4857_dapm_widgets));
400 if (ret)
401 return ret;
402
403 ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes,
404 ARRAY_SIZE(neo1973_lm4857_routes));
405 if (ret)
406 return ret;
407
408 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
409 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
410 snd_soc_dapm_ignore_suspend(dapm, "Headphone");
411
412 snd_soc_dapm_sync(dapm);
413
414 return 0;
415}
416
417#else
418static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; };
419#endif
420
556static struct snd_soc_dai_link neo1973_dai[] = { 421static struct snd_soc_dai_link neo1973_dai[] = {
557{ /* Hifi Playback - for similatious use with voice below */ 422{ /* Hifi Playback - for similatious use with voice below */
558 .name = "WM8753", 423 .name = "WM8753",
@@ -568,90 +433,49 @@ static struct snd_soc_dai_link neo1973_dai[] = {
568 .name = "Bluetooth", 433 .name = "Bluetooth",
569 .stream_name = "Voice", 434 .stream_name = "Voice",
570 .platform_name = "samsung-audio", 435 .platform_name = "samsung-audio",
571 .cpu_dai_name = "bluetooth-dai", 436 .cpu_dai_name = "dfbmcs320-pcm",
572 .codec_dai_name = "wm8753-voice", 437 .codec_dai_name = "wm8753-voice",
573 .codec_name = "wm8753-codec.0-001a", 438 .codec_name = "wm8753-codec.0-001a",
574 .ops = &neo1973_voice_ops, 439 .ops = &neo1973_voice_ops,
575}, 440},
576}; 441};
577 442
578static struct snd_soc_card neo1973 = { 443static struct snd_soc_aux_dev neo1973_aux_devs[] = {
579 .name = "neo1973", 444 {
580 .dai_link = neo1973_dai, 445 .name = "dfbmcs320",
581 .num_links = ARRAY_SIZE(neo1973_dai), 446 .codec_name = "dfbmcs320.0",
447 },
448 {
449 .name = "lm4857",
450 .codec_name = "lm4857.0-007c",
451 .init = neo1973_lm4857_init,
452 },
582}; 453};
583 454
584static int lm4857_i2c_probe(struct i2c_client *client, 455static struct snd_soc_codec_conf neo1973_codec_conf[] = {
585 const struct i2c_device_id *id) 456 {
586{ 457 .dev_name = "lm4857.0-007c",
587 pr_debug("Entered %s\n", __func__); 458 .name_prefix = "Amp",
588 459 },
589 i2c = client; 460};
590
591 lm4857_write_regs();
592 return 0;
593}
594
595static int lm4857_i2c_remove(struct i2c_client *client)
596{
597 pr_debug("Entered %s\n", __func__);
598
599 i2c = NULL;
600
601 return 0;
602}
603
604static u8 lm4857_state;
605
606static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
607{
608 pr_debug("Entered %s\n", __func__);
609
610 dev_dbg(&dev->dev, "lm4857_suspend\n");
611 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
612 if (lm4857_state) {
613 lm4857_regs[LM4857_CTRL] &= 0xf0;
614 lm4857_write_regs();
615 }
616 return 0;
617}
618
619static int lm4857_resume(struct i2c_client *dev)
620{
621 pr_debug("Entered %s\n", __func__);
622
623 if (lm4857_state) {
624 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
625 lm4857_write_regs();
626 }
627 return 0;
628}
629
630static void lm4857_shutdown(struct i2c_client *dev)
631{
632 pr_debug("Entered %s\n", __func__);
633
634 dev_dbg(&dev->dev, "lm4857_shutdown\n");
635 lm4857_regs[LM4857_CTRL] &= 0xf0;
636 lm4857_write_regs();
637}
638 461
639static const struct i2c_device_id lm4857_i2c_id[] = { 462#ifdef CONFIG_MACH_NEO1973_GTA02
640 { "neo1973_lm4857", 0 }, 463static const struct gpio neo1973_gta02_gpios[] = {
641 { } 464 { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
465 { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
642}; 466};
467#else
468static const struct gpio neo1973_gta02_gpios[] = {};
469#endif
643 470
644static struct i2c_driver lm4857_i2c_driver = { 471static struct snd_soc_card neo1973 = {
645 .driver = { 472 .name = "neo1973",
646 .name = "LM4857 I2C Amp", 473 .dai_link = neo1973_dai,
647 .owner = THIS_MODULE, 474 .num_links = ARRAY_SIZE(neo1973_dai),
648 }, 475 .aux_dev = neo1973_aux_devs,
649 .suspend = lm4857_suspend, 476 .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
650 .resume = lm4857_resume, 477 .codec_conf = neo1973_codec_conf,
651 .shutdown = lm4857_shutdown, 478 .num_configs = ARRAY_SIZE(neo1973_codec_conf),
652 .probe = lm4857_i2c_probe,
653 .remove = lm4857_i2c_remove,
654 .id_table = lm4857_i2c_id,
655}; 479};
656 480
657static struct platform_device *neo1973_snd_device; 481static struct platform_device *neo1973_snd_device;
@@ -660,46 +484,56 @@ static int __init neo1973_init(void)
660{ 484{
661 int ret; 485 int ret;
662 486
663 pr_debug("Entered %s\n", __func__); 487 if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02())
664
665 if (!machine_is_neo1973_gta01()) {
666 printk(KERN_INFO
667 "Only GTA01 hardware supported by ASoC driver\n");
668 return -ENODEV; 488 return -ENODEV;
489
490 if (machine_is_neo1973_gta02()) {
491 neo1973.name = "neo1973gta02";
492 neo1973.num_aux_devs = 1;
493
494 ret = gpio_request_array(neo1973_gta02_gpios,
495 ARRAY_SIZE(neo1973_gta02_gpios));
496 if (ret)
497 return ret;
669 } 498 }
670 499
671 neo1973_snd_device = platform_device_alloc("soc-audio", -1); 500 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
672 if (!neo1973_snd_device) 501 if (!neo1973_snd_device) {
673 return -ENOMEM; 502 ret = -ENOMEM;
503 goto err_gpio_free;
504 }
674 505
675 platform_set_drvdata(neo1973_snd_device, &neo1973); 506 platform_set_drvdata(neo1973_snd_device, &neo1973);
676 ret = platform_device_add(neo1973_snd_device); 507 ret = platform_device_add(neo1973_snd_device);
677 508
678 if (ret) { 509 if (ret)
679 platform_device_put(neo1973_snd_device); 510 goto err_put_device;
680 return ret;
681 }
682
683 ret = i2c_add_driver(&lm4857_i2c_driver);
684 511
685 if (ret != 0) 512 return 0;
686 platform_device_unregister(neo1973_snd_device);
687 513
514err_put_device:
515 platform_device_put(neo1973_snd_device);
516err_gpio_free:
517 if (machine_is_neo1973_gta02()) {
518 gpio_free_array(neo1973_gta02_gpios,
519 ARRAY_SIZE(neo1973_gta02_gpios));
520 }
688 return ret; 521 return ret;
689} 522}
523module_init(neo1973_init);
690 524
691static void __exit neo1973_exit(void) 525static void __exit neo1973_exit(void)
692{ 526{
693 pr_debug("Entered %s\n", __func__);
694
695 i2c_del_driver(&lm4857_i2c_driver);
696 platform_device_unregister(neo1973_snd_device); 527 platform_device_unregister(neo1973_snd_device);
697}
698 528
699module_init(neo1973_init); 529 if (machine_is_neo1973_gta02()) {
530 gpio_free_array(neo1973_gta02_gpios,
531 ARRAY_SIZE(neo1973_gta02_gpios));
532 }
533}
700module_exit(neo1973_exit); 534module_exit(neo1973_exit);
701 535
702/* Module information */ 536/* Module information */
703MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); 537MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
704MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); 538MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner");
705MODULE_LICENSE("GPL"); 539MODULE_LICENSE("GPL");
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index db66dc44add2..5d76da43b14c 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -1609,24 +1609,23 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
1609 return 0; 1609 return 0;
1610 } 1610 }
1611 1611
1612 if (!codec->cache_ops || !codec->cache_ops->sync)
1613 return -EINVAL;
1614
1612 if (codec->cache_ops->name) 1615 if (codec->cache_ops->name)
1613 name = codec->cache_ops->name; 1616 name = codec->cache_ops->name;
1614 else 1617 else
1615 name = "unknown"; 1618 name = "unknown";
1616 1619
1617 if (codec->cache_ops && codec->cache_ops->sync) { 1620 if (codec->cache_ops->name)
1618 if (codec->cache_ops->name) 1621 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1619 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n", 1622 codec->cache_ops->name, codec->name);
1620 codec->cache_ops->name, codec->name); 1623 trace_snd_soc_cache_sync(codec, name, "start");
1621 trace_snd_soc_cache_sync(codec, name, "start"); 1624 ret = codec->cache_ops->sync(codec);
1622 ret = codec->cache_ops->sync(codec); 1625 if (!ret)
1623 if (!ret) 1626 codec->cache_sync = 0;
1624 codec->cache_sync = 0; 1627 trace_snd_soc_cache_sync(codec, name, "end");
1625 trace_snd_soc_cache_sync(codec, name, "end"); 1628 return ret;
1626 return ret;
1627 }
1628
1629 return -EINVAL;
1630} 1629}
1631EXPORT_SYMBOL_GPL(snd_soc_cache_sync); 1630EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
1632 1631
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 205cbd7b149f..17efacdb248a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -87,15 +87,56 @@ static int min_bytes_needed(unsigned long val)
87 return c; 87 return c;
88} 88}
89 89
90/* fill buf which is 'len' bytes with a formatted
91 * string of the form 'reg: value\n' */
92static int format_register_str(struct snd_soc_codec *codec,
93 unsigned int reg, char *buf, size_t len)
94{
95 int wordsize = codec->driver->reg_word_size * 2;
96 int regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
97 int ret;
98 char tmpbuf[len + 1];
99 char regbuf[regsize + 1];
100
101 /* since tmpbuf is allocated on the stack, warn the callers if they
102 * try to abuse this function */
103 WARN_ON(len > 63);
104
105 /* +2 for ': ' and + 1 for '\n' */
106 if (wordsize + regsize + 2 + 1 != len)
107 return -EINVAL;
108
109 ret = snd_soc_read(codec , reg);
110 if (ret < 0) {
111 memset(regbuf, 'X', regsize);
112 regbuf[regsize] = '\0';
113 } else {
114 snprintf(regbuf, regsize + 1, "%.*x", regsize, ret);
115 }
116
117 /* prepare the buffer */
118 snprintf(tmpbuf, len + 1, "%.*x: %s\n", wordsize, reg, regbuf);
119 /* copy it back to the caller without the '\0' */
120 memcpy(buf, tmpbuf, len);
121
122 return 0;
123}
124
90/* codec register dump */ 125/* codec register dump */
91static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 126static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
127 size_t count, loff_t pos)
92{ 128{
93 int ret, i, step = 1, count = 0; 129 int i, step = 1;
94 int wordsize, regsize; 130 int wordsize, regsize;
131 int len;
132 size_t total = 0;
133 loff_t p = 0;
95 134
96 wordsize = codec->driver->reg_word_size * 2; 135 wordsize = codec->driver->reg_word_size * 2;
97 regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2; 136 regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
98 137
138 len = wordsize + regsize + 2 + 1;
139
99 if (!codec->driver->reg_cache_size) 140 if (!codec->driver->reg_cache_size)
100 return 0; 141 return 0;
101 142
@@ -105,51 +146,34 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
105 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 146 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
106 if (codec->readable_register && !codec->readable_register(codec, i)) 147 if (codec->readable_register && !codec->readable_register(codec, i))
107 continue; 148 continue;
108
109 count += sprintf(buf + count, "%.*x: ", regsize, i);
110 if (count >= PAGE_SIZE - 1)
111 break;
112
113 if (codec->driver->display_register) { 149 if (codec->driver->display_register) {
114 count += codec->driver->display_register(codec, buf + count, 150 count += codec->driver->display_register(codec, buf + count,
115 PAGE_SIZE - count, i); 151 PAGE_SIZE - count, i);
116 } else { 152 } else {
117 /* If the read fails it's almost certainly due to 153 /* only support larger than PAGE_SIZE bytes debugfs
118 * the register being volatile and the device being 154 * entries for the default case */
119 * powered off. 155 if (p >= pos) {
120 */ 156 if (total + len >= count - 1)
121 ret = snd_soc_read(codec, i); 157 break;
122 if (ret >= 0) 158 format_register_str(codec, i, buf + total, len);
123 count += snprintf(buf + count, 159 total += len;
124 PAGE_SIZE - count, 160 }
125 "%.*x", wordsize, ret); 161 p += len;
126 else
127 count += snprintf(buf + count,
128 PAGE_SIZE - count,
129 "<no data: %d>", ret);
130 } 162 }
131
132 if (count >= PAGE_SIZE - 1)
133 break;
134
135 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
136 if (count >= PAGE_SIZE - 1)
137 break;
138 } 163 }
139 164
140 /* Truncate count; min() would cause a warning */ 165 total = min(total, count - 1);
141 if (count >= PAGE_SIZE)
142 count = PAGE_SIZE - 1;
143 166
144 return count; 167 return total;
145} 168}
169
146static ssize_t codec_reg_show(struct device *dev, 170static ssize_t codec_reg_show(struct device *dev,
147 struct device_attribute *attr, char *buf) 171 struct device_attribute *attr, char *buf)
148{ 172{
149 struct snd_soc_pcm_runtime *rtd = 173 struct snd_soc_pcm_runtime *rtd =
150 container_of(dev, struct snd_soc_pcm_runtime, dev); 174 container_of(dev, struct snd_soc_pcm_runtime, dev);
151 175
152 return soc_codec_reg_show(rtd->codec, buf); 176 return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
153} 177}
154 178
155static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 179static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
@@ -188,16 +212,28 @@ static int codec_reg_open_file(struct inode *inode, struct file *file)
188} 212}
189 213
190static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, 214static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
191 size_t count, loff_t *ppos) 215 size_t count, loff_t *ppos)
192{ 216{
193 ssize_t ret; 217 ssize_t ret;
194 struct snd_soc_codec *codec = file->private_data; 218 struct snd_soc_codec *codec = file->private_data;
195 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 219 char *buf;
220
221 if (*ppos < 0 || !count)
222 return -EINVAL;
223
224 buf = kmalloc(count, GFP_KERNEL);
196 if (!buf) 225 if (!buf)
197 return -ENOMEM; 226 return -ENOMEM;
198 ret = soc_codec_reg_show(codec, buf); 227
199 if (ret >= 0) 228 ret = soc_codec_reg_show(codec, buf, count, *ppos);
200 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 229 if (ret >= 0) {
230 if (copy_to_user(user_buf, buf, ret)) {
231 kfree(buf);
232 return -EFAULT;
233 }
234 *ppos += ret;
235 }
236
201 kfree(buf); 237 kfree(buf);
202 return ret; 238 return ret;
203} 239}
@@ -464,20 +500,30 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
464 struct snd_soc_dai *codec_dai = rtd->codec_dai; 500 struct snd_soc_dai *codec_dai = rtd->codec_dai;
465 int ret; 501 int ret;
466 502
467 if (codec_dai->driver->symmetric_rates || cpu_dai->driver->symmetric_rates || 503 if (!codec_dai->driver->symmetric_rates &&
468 rtd->dai_link->symmetric_rates) { 504 !cpu_dai->driver->symmetric_rates &&
469 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", 505 !rtd->dai_link->symmetric_rates)
470 rtd->rate); 506 return 0;
471 507
472 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 508 /* This can happen if multiple streams are starting simultaneously -
473 SNDRV_PCM_HW_PARAM_RATE, 509 * the second can need to get its constraints before the first has
474 rtd->rate, 510 * picked a rate. Complain and allow the application to carry on.
475 rtd->rate); 511 */
476 if (ret < 0) { 512 if (!rtd->rate) {
477 dev_err(&rtd->dev, 513 dev_warn(&rtd->dev,
478 "Unable to apply rate symmetry constraint: %d\n", ret); 514 "Not enforcing symmetric_rates due to race\n");
479 return ret; 515 return 0;
480 } 516 }
517
518 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate);
519
520 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
521 SNDRV_PCM_HW_PARAM_RATE,
522 rtd->rate, rtd->rate);
523 if (ret < 0) {
524 dev_err(&rtd->dev,
525 "Unable to apply rate symmetry constraint: %d\n", ret);
526 return ret;
481 } 527 }
482 528
483 return 0; 529 return 0;
@@ -1428,6 +1474,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
1428 struct snd_soc_codec *codec) 1474 struct snd_soc_codec *codec)
1429{ 1475{
1430 int ret = 0; 1476 int ret = 0;
1477 const struct snd_soc_codec_driver *driver = codec->driver;
1431 1478
1432 codec->card = card; 1479 codec->card = card;
1433 codec->dapm.card = card; 1480 codec->dapm.card = card;
@@ -1436,8 +1483,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
1436 if (!try_module_get(codec->dev->driver->owner)) 1483 if (!try_module_get(codec->dev->driver->owner))
1437 return -ENODEV; 1484 return -ENODEV;
1438 1485
1439 if (codec->driver->probe) { 1486 if (driver->probe) {
1440 ret = codec->driver->probe(codec); 1487 ret = driver->probe(codec);
1441 if (ret < 0) { 1488 if (ret < 0) {
1442 dev_err(codec->dev, 1489 dev_err(codec->dev,
1443 "asoc: failed to probe CODEC %s: %d\n", 1490 "asoc: failed to probe CODEC %s: %d\n",
@@ -1446,6 +1493,13 @@ static int soc_probe_codec(struct snd_soc_card *card,
1446 } 1493 }
1447 } 1494 }
1448 1495
1496 if (driver->dapm_widgets)
1497 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
1498 driver->num_dapm_widgets);
1499 if (driver->dapm_routes)
1500 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
1501 driver->num_dapm_routes);
1502
1449 soc_init_codec_debugfs(codec); 1503 soc_init_codec_debugfs(codec);
1450 1504
1451 /* mark codec as probed and add to card codec list */ 1505 /* mark codec as probed and add to card codec list */
@@ -1482,6 +1536,7 @@ static int soc_post_component_init(struct snd_soc_card *card,
1482 rtd = &card->rtd_aux[num]; 1536 rtd = &card->rtd_aux[num];
1483 name = aux_dev->name; 1537 name = aux_dev->name;
1484 } 1538 }
1539 rtd->card = card;
1485 1540
1486 /* machine controls, routes and widgets are not prefixed */ 1541 /* machine controls, routes and widgets are not prefixed */
1487 temp = codec->name_prefix; 1542 temp = codec->name_prefix;
@@ -1503,7 +1558,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1503 1558
1504 /* register the rtd device */ 1559 /* register the rtd device */
1505 rtd->codec = codec; 1560 rtd->codec = codec;
1506 rtd->card = card;
1507 rtd->dev.parent = card->dev; 1561 rtd->dev.parent = card->dev;
1508 rtd->dev.release = rtd_release; 1562 rtd->dev.release = rtd_release;
1509 rtd->dev.init_name = name; 1563 rtd->dev.init_name = name;
@@ -1801,7 +1855,12 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1801 } 1855 }
1802 card->snd_card->dev = card->dev; 1856 card->snd_card->dev = card->dev;
1803 1857
1804#ifdef CONFIG_PM 1858 card->dapm.bias_level = SND_SOC_BIAS_OFF;
1859 card->dapm.dev = card->dev;
1860 card->dapm.card = card;
1861 list_add(&card->dapm.list, &card->dapm_list);
1862
1863#ifdef CONFIG_PM_SLEEP
1805 /* deferred resume work */ 1864 /* deferred resume work */
1806 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1865 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1807#endif 1866#endif
@@ -1831,11 +1890,37 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1831 } 1890 }
1832 } 1891 }
1833 1892
1893 if (card->dapm_widgets)
1894 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1895 card->num_dapm_widgets);
1896 if (card->dapm_routes)
1897 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1898 card->num_dapm_routes);
1899
1900#ifdef CONFIG_DEBUG_FS
1901 card->dapm.debugfs_dapm = debugfs_create_dir("dapm",
1902 card->debugfs_card_root);
1903 if (!card->dapm.debugfs_dapm)
1904 printk(KERN_WARNING
1905 "Failed to create card DAPM debugfs directory\n");
1906
1907 snd_soc_dapm_debugfs_init(&card->dapm);
1908#endif
1909
1834 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1910 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1835 "%s", card->name); 1911 "%s", card->name);
1836 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1912 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1837 "%s", card->name); 1913 "%s", card->name);
1838 1914
1915 if (card->late_probe) {
1916 ret = card->late_probe(card);
1917 if (ret < 0) {
1918 dev_err(card->dev, "%s late_probe() failed: %d\n",
1919 card->name, ret);
1920 goto probe_aux_dev_err;
1921 }
1922 }
1923
1839 ret = snd_card_register(card->snd_card); 1924 ret = snd_card_register(card->snd_card);
1840 if (ret < 0) { 1925 if (ret < 0) {
1841 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1926 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
@@ -2259,22 +2344,45 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
2259 * @_template: control template 2344 * @_template: control template
2260 * @data: control private data 2345 * @data: control private data
2261 * @long_name: control long name 2346 * @long_name: control long name
2347 * @prefix: control name prefix
2262 * 2348 *
2263 * Create a new mixer control from a template control. 2349 * Create a new mixer control from a template control.
2264 * 2350 *
2265 * Returns 0 for success, else error. 2351 * Returns 0 for success, else error.
2266 */ 2352 */
2267struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 2353struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2268 void *data, char *long_name) 2354 void *data, char *long_name,
2355 const char *prefix)
2269{ 2356{
2270 struct snd_kcontrol_new template; 2357 struct snd_kcontrol_new template;
2358 struct snd_kcontrol *kcontrol;
2359 char *name = NULL;
2360 int name_len;
2271 2361
2272 memcpy(&template, _template, sizeof(template)); 2362 memcpy(&template, _template, sizeof(template));
2273 if (long_name)
2274 template.name = long_name;
2275 template.index = 0; 2363 template.index = 0;
2276 2364
2277 return snd_ctl_new1(&template, data); 2365 if (!long_name)
2366 long_name = template.name;
2367
2368 if (prefix) {
2369 name_len = strlen(long_name) + strlen(prefix) + 2;
2370 name = kmalloc(name_len, GFP_ATOMIC);
2371 if (!name)
2372 return NULL;
2373
2374 snprintf(name, name_len, "%s %s", prefix, long_name);
2375
2376 template.name = name;
2377 } else {
2378 template.name = long_name;
2379 }
2380
2381 kcontrol = snd_ctl_new1(&template, data);
2382
2383 kfree(name);
2384
2385 return kcontrol;
2278} 2386}
2279EXPORT_SYMBOL_GPL(snd_soc_cnew); 2387EXPORT_SYMBOL_GPL(snd_soc_cnew);
2280 2388
@@ -2293,22 +2401,16 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
2293 const struct snd_kcontrol_new *controls, int num_controls) 2401 const struct snd_kcontrol_new *controls, int num_controls)
2294{ 2402{
2295 struct snd_card *card = codec->card->snd_card; 2403 struct snd_card *card = codec->card->snd_card;
2296 char prefixed_name[44], *name;
2297 int err, i; 2404 int err, i;
2298 2405
2299 for (i = 0; i < num_controls; i++) { 2406 for (i = 0; i < num_controls; i++) {
2300 const struct snd_kcontrol_new *control = &controls[i]; 2407 const struct snd_kcontrol_new *control = &controls[i];
2301 if (codec->name_prefix) { 2408 err = snd_ctl_add(card, snd_soc_cnew(control, codec,
2302 snprintf(prefixed_name, sizeof(prefixed_name), "%s %s", 2409 control->name,
2303 codec->name_prefix, control->name); 2410 codec->name_prefix));
2304 name = prefixed_name;
2305 } else {
2306 name = control->name;
2307 }
2308 err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
2309 if (err < 0) { 2411 if (err < 0) {
2310 dev_err(codec->dev, "%s: Failed to add %s: %d\n", 2412 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2311 codec->name, name, err); 2413 codec->name, control->name, err);
2312 return err; 2414 return err;
2313 } 2415 }
2314 } 2416 }
@@ -2989,12 +3091,34 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2989{ 3091{
2990 if (dai->driver && dai->driver->ops->set_sysclk) 3092 if (dai->driver && dai->driver->ops->set_sysclk)
2991 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); 3093 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
3094 else if (dai->codec && dai->codec->driver->set_sysclk)
3095 return dai->codec->driver->set_sysclk(dai->codec, clk_id,
3096 freq, dir);
2992 else 3097 else
2993 return -EINVAL; 3098 return -EINVAL;
2994} 3099}
2995EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); 3100EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2996 3101
2997/** 3102/**
3103 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
3104 * @codec: CODEC
3105 * @clk_id: DAI specific clock ID
3106 * @freq: new clock frequency in Hz
3107 * @dir: new clock direction - input/output.
3108 *
3109 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
3110 */
3111int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
3112 unsigned int freq, int dir)
3113{
3114 if (codec->driver->set_sysclk)
3115 return codec->driver->set_sysclk(codec, clk_id, freq, dir);
3116 else
3117 return -EINVAL;
3118}
3119EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
3120
3121/**
2998 * snd_soc_dai_set_clkdiv - configure DAI clock dividers. 3122 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
2999 * @dai: DAI 3123 * @dai: DAI
3000 * @div_id: DAI specific clock divider ID 3124 * @div_id: DAI specific clock divider ID
@@ -3030,11 +3154,35 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
3030 if (dai->driver && dai->driver->ops->set_pll) 3154 if (dai->driver && dai->driver->ops->set_pll)
3031 return dai->driver->ops->set_pll(dai, pll_id, source, 3155 return dai->driver->ops->set_pll(dai, pll_id, source,
3032 freq_in, freq_out); 3156 freq_in, freq_out);
3157 else if (dai->codec && dai->codec->driver->set_pll)
3158 return dai->codec->driver->set_pll(dai->codec, pll_id, source,
3159 freq_in, freq_out);
3033 else 3160 else
3034 return -EINVAL; 3161 return -EINVAL;
3035} 3162}
3036EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); 3163EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
3037 3164
3165/*
3166 * snd_soc_codec_set_pll - configure codec PLL.
3167 * @codec: CODEC
3168 * @pll_id: DAI specific PLL ID
3169 * @source: DAI specific source for the PLL
3170 * @freq_in: PLL input clock frequency in Hz
3171 * @freq_out: requested PLL output clock frequency in Hz
3172 *
3173 * Configures and enables PLL to generate output clock based on input clock.
3174 */
3175int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
3176 unsigned int freq_in, unsigned int freq_out)
3177{
3178 if (codec->driver->set_pll)
3179 return codec->driver->set_pll(codec, pll_id, source,
3180 freq_in, freq_out);
3181 else
3182 return -EINVAL;
3183}
3184EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
3185
3038/** 3186/**
3039 * snd_soc_dai_set_fmt - configure DAI hardware audio format. 3187 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
3040 * @dai: DAI 3188 * @dai: DAI
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d0342aab2c15..81c4052c127c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/async.h>
35#include <linux/delay.h> 36#include <linux/delay.h>
36#include <linux/pm.h> 37#include <linux/pm.h>
37#include <linux/bitops.h> 38#include <linux/bitops.h>
@@ -125,17 +126,17 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
125 126
126/** 127/**
127 * snd_soc_dapm_set_bias_level - set the bias level for the system 128 * snd_soc_dapm_set_bias_level - set the bias level for the system
128 * @card: audio device 129 * @dapm: DAPM context
129 * @level: level to configure 130 * @level: level to configure
130 * 131 *
131 * Configure the bias (power) levels for the SoC audio device. 132 * Configure the bias (power) levels for the SoC audio device.
132 * 133 *
133 * Returns 0 for success else error. 134 * Returns 0 for success else error.
134 */ 135 */
135static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, 136static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
136 struct snd_soc_dapm_context *dapm,
137 enum snd_soc_bias_level level) 137 enum snd_soc_bias_level level)
138{ 138{
139 struct snd_soc_card *card = dapm->card;
139 int ret = 0; 140 int ret = 0;
140 141
141 switch (level) { 142 switch (level) {
@@ -365,9 +366,20 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
365 struct snd_soc_dapm_widget *w) 366 struct snd_soc_dapm_widget *w)
366{ 367{
367 int i, ret = 0; 368 int i, ret = 0;
368 size_t name_len; 369 size_t name_len, prefix_len;
369 struct snd_soc_dapm_path *path; 370 struct snd_soc_dapm_path *path;
370 struct snd_card *card = dapm->codec->card->snd_card; 371 struct snd_card *card = dapm->card->snd_card;
372 const char *prefix;
373
374 if (dapm->codec)
375 prefix = dapm->codec->name_prefix;
376 else
377 prefix = NULL;
378
379 if (prefix)
380 prefix_len = strlen(prefix) + 1;
381 else
382 prefix_len = 0;
371 383
372 /* add kcontrol */ 384 /* add kcontrol */
373 for (i = 0; i < w->num_kcontrols; i++) { 385 for (i = 0; i < w->num_kcontrols; i++) {
@@ -396,8 +408,15 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
396 408
397 switch (w->id) { 409 switch (w->id) {
398 default: 410 default:
411 /* The control will get a prefix from
412 * the control creation process but
413 * we're also using the same prefix
414 * for widgets so cut the prefix off
415 * the front of the widget name.
416 */
399 snprintf(path->long_name, name_len, "%s %s", 417 snprintf(path->long_name, name_len, "%s %s",
400 w->name, w->kcontrols[i].name); 418 w->name + prefix_len,
419 w->kcontrols[i].name);
401 break; 420 break;
402 case snd_soc_dapm_mixer_named_ctl: 421 case snd_soc_dapm_mixer_named_ctl:
403 snprintf(path->long_name, name_len, "%s", 422 snprintf(path->long_name, name_len, "%s",
@@ -408,7 +427,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
408 path->long_name[name_len - 1] = '\0'; 427 path->long_name[name_len - 1] = '\0';
409 428
410 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 429 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
411 path->long_name); 430 path->long_name, prefix);
412 ret = snd_ctl_add(card, path->kcontrol); 431 ret = snd_ctl_add(card, path->kcontrol);
413 if (ret < 0) { 432 if (ret < 0) {
414 dev_err(dapm->dev, 433 dev_err(dapm->dev,
@@ -429,7 +448,9 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
429{ 448{
430 struct snd_soc_dapm_path *path = NULL; 449 struct snd_soc_dapm_path *path = NULL;
431 struct snd_kcontrol *kcontrol; 450 struct snd_kcontrol *kcontrol;
432 struct snd_card *card = dapm->codec->card->snd_card; 451 struct snd_card *card = dapm->card->snd_card;
452 const char *prefix;
453 size_t prefix_len;
433 int ret = 0; 454 int ret = 0;
434 455
435 if (!w->num_kcontrols) { 456 if (!w->num_kcontrols) {
@@ -437,7 +458,22 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
437 return -EINVAL; 458 return -EINVAL;
438 } 459 }
439 460
440 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 461 if (dapm->codec)
462 prefix = dapm->codec->name_prefix;
463 else
464 prefix = NULL;
465
466 if (prefix)
467 prefix_len = strlen(prefix) + 1;
468 else
469 prefix_len = 0;
470
471 /* The control will get a prefix from the control creation
472 * process but we're also using the same prefix for widgets so
473 * cut the prefix off the front of the widget name.
474 */
475 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name + prefix_len,
476 prefix);
441 ret = snd_ctl_add(card, kcontrol); 477 ret = snd_ctl_add(card, kcontrol);
442 478
443 if (ret < 0) 479 if (ret < 0)
@@ -479,7 +515,7 @@ static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
479 */ 515 */
480static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 516static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
481{ 517{
482 int level = snd_power_get_state(widget->dapm->codec->card->snd_card); 518 int level = snd_power_get_state(widget->dapm->card->snd_card);
483 519
484 switch (level) { 520 switch (level) {
485 case SNDRV_CTL_POWER_D3hot: 521 case SNDRV_CTL_POWER_D3hot:
@@ -712,7 +748,15 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
712 !path->connected(path->source, path->sink)) 748 !path->connected(path->source, path->sink))
713 continue; 749 continue;
714 750
715 if (path->sink && path->sink->power_check && 751 if (!path->sink)
752 continue;
753
754 if (path->sink->force) {
755 power = 1;
756 break;
757 }
758
759 if (path->sink->power_check &&
716 path->sink->power_check(path->sink)) { 760 path->sink->power_check(path->sink)) {
717 power = 1; 761 power = 1;
718 break; 762 break;
@@ -963,7 +1007,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
963 } 1007 }
964 1008
965 if (!list_empty(&pending)) 1009 if (!list_empty(&pending))
966 dapm_seq_run_coalesced(dapm, &pending); 1010 dapm_seq_run_coalesced(cur_dapm, &pending);
967 1011
968 if (cur_dapm && cur_dapm->seq_notifier) { 1012 if (cur_dapm && cur_dapm->seq_notifier) {
969 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1013 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
@@ -1006,7 +1050,62 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
1006 } 1050 }
1007} 1051}
1008 1052
1053/* Async callback run prior to DAPM sequences - brings to _PREPARE if
1054 * they're changing state.
1055 */
1056static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1057{
1058 struct snd_soc_dapm_context *d = data;
1059 int ret;
1009 1060
1061 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
1062 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1063 if (ret != 0)
1064 dev_err(d->dev,
1065 "Failed to turn on bias: %d\n", ret);
1066 }
1067
1068 /* If we're changing to all on or all off then prepare */
1069 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1070 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1071 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
1072 if (ret != 0)
1073 dev_err(d->dev,
1074 "Failed to prepare bias: %d\n", ret);
1075 }
1076}
1077
1078/* Async callback run prior to DAPM sequences - brings to their final
1079 * state.
1080 */
1081static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1082{
1083 struct snd_soc_dapm_context *d = data;
1084 int ret;
1085
1086 /* If we just powered the last thing off drop to standby bias */
1087 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1088 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1089 if (ret != 0)
1090 dev_err(d->dev, "Failed to apply standby bias: %d\n",
1091 ret);
1092 }
1093
1094 /* If we're in standby and can support bias off then do that */
1095 if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) {
1096 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
1097 if (ret != 0)
1098 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1099 }
1100
1101 /* If we just powered up then move to active bias */
1102 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1103 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
1104 if (ret != 0)
1105 dev_err(d->dev, "Failed to apply active bias: %d\n",
1106 ret);
1107 }
1108}
1010 1109
1011/* 1110/*
1012 * Scan each dapm widget for complete audio path. 1111 * Scan each dapm widget for complete audio path.
@@ -1019,12 +1118,12 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
1019 */ 1118 */
1020static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) 1119static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1021{ 1120{
1022 struct snd_soc_card *card = dapm->codec->card; 1121 struct snd_soc_card *card = dapm->card;
1023 struct snd_soc_dapm_widget *w; 1122 struct snd_soc_dapm_widget *w;
1024 struct snd_soc_dapm_context *d; 1123 struct snd_soc_dapm_context *d;
1025 LIST_HEAD(up_list); 1124 LIST_HEAD(up_list);
1026 LIST_HEAD(down_list); 1125 LIST_HEAD(down_list);
1027 int ret = 0; 1126 LIST_HEAD(async_domain);
1028 int power; 1127 int power;
1029 1128
1030 trace_snd_soc_dapm_start(card); 1129 trace_snd_soc_dapm_start(card);
@@ -1102,25 +1201,11 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1102 } 1201 }
1103 } 1202 }
1104 1203
1105 list_for_each_entry(d, &dapm->card->dapm_list, list) { 1204 /* Run all the bias changes in parallel */
1106 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) { 1205 list_for_each_entry(d, &dapm->card->dapm_list, list)
1107 ret = snd_soc_dapm_set_bias_level(card, d, 1206 async_schedule_domain(dapm_pre_sequence_async, d,
1108 SND_SOC_BIAS_STANDBY); 1207 &async_domain);
1109 if (ret != 0) 1208 async_synchronize_full_domain(&async_domain);
1110 dev_err(d->dev,
1111 "Failed to turn on bias: %d\n", ret);
1112 }
1113
1114 /* If we're changing to all on or all off then prepare */
1115 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1116 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1117 ret = snd_soc_dapm_set_bias_level(card, d,
1118 SND_SOC_BIAS_PREPARE);
1119 if (ret != 0)
1120 dev_err(d->dev,
1121 "Failed to prepare bias: %d\n", ret);
1122 }
1123 }
1124 1209
1125 /* Power down widgets first; try to avoid amplifying pops. */ 1210 /* Power down widgets first; try to avoid amplifying pops. */
1126 dapm_seq_run(dapm, &down_list, event, false); 1211 dapm_seq_run(dapm, &down_list, event, false);
@@ -1130,37 +1215,11 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1130 /* Now power up. */ 1215 /* Now power up. */
1131 dapm_seq_run(dapm, &up_list, event, true); 1216 dapm_seq_run(dapm, &up_list, event, true);
1132 1217
1133 list_for_each_entry(d, &dapm->card->dapm_list, list) { 1218 /* Run all the bias changes in parallel */
1134 /* If we just powered the last thing off drop to standby bias */ 1219 list_for_each_entry(d, &dapm->card->dapm_list, list)
1135 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) { 1220 async_schedule_domain(dapm_post_sequence_async, d,
1136 ret = snd_soc_dapm_set_bias_level(card, d, 1221 &async_domain);
1137 SND_SOC_BIAS_STANDBY); 1222 async_synchronize_full_domain(&async_domain);
1138 if (ret != 0)
1139 dev_err(d->dev,
1140 "Failed to apply standby bias: %d\n",
1141 ret);
1142 }
1143
1144 /* If we're in standby and can support bias off then do that */
1145 if (d->bias_level == SND_SOC_BIAS_STANDBY &&
1146 d->idle_bias_off) {
1147 ret = snd_soc_dapm_set_bias_level(card, d,
1148 SND_SOC_BIAS_OFF);
1149 if (ret != 0)
1150 dev_err(d->dev,
1151 "Failed to turn off bias: %d\n", ret);
1152 }
1153
1154 /* If we just powered up then move to active bias */
1155 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1156 ret = snd_soc_dapm_set_bias_level(card, d,
1157 SND_SOC_BIAS_ON);
1158 if (ret != 0)
1159 dev_err(d->dev,
1160 "Failed to apply active bias: %d\n",
1161 ret);
1162 }
1163 }
1164 1223
1165 pop_dbg(dapm->dev, card->pop_time, 1224 pop_dbg(dapm->dev, card->pop_time,
1166 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1225 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
@@ -1218,7 +1277,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1218 1277
1219 if (p->connect) 1278 if (p->connect)
1220 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1279 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1221 " in %s %s\n", 1280 " in \"%s\" \"%s\"\n",
1222 p->name ? p->name : "static", 1281 p->name ? p->name : "static",
1223 p->source->name); 1282 p->source->name);
1224 } 1283 }
@@ -1228,7 +1287,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1228 1287
1229 if (p->connect) 1288 if (p->connect)
1230 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1289 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1231 " out %s %s\n", 1290 " out \"%s\" \"%s\"\n",
1232 p->name ? p->name : "static", 1291 p->name ? p->name : "static",
1233 p->sink->name); 1292 p->sink->name);
1234 } 1293 }
@@ -1493,7 +1552,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1493 char prefixed_source[80]; 1552 char prefixed_source[80];
1494 int ret = 0; 1553 int ret = 0;
1495 1554
1496 if (dapm->codec->name_prefix) { 1555 if (dapm->codec && dapm->codec->name_prefix) {
1497 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 1556 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
1498 dapm->codec->name_prefix, route->sink); 1557 dapm->codec->name_prefix, route->sink);
1499 sink = prefixed_sink; 1558 sink = prefixed_sink;
@@ -1664,6 +1723,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1664int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) 1723int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1665{ 1724{
1666 struct snd_soc_dapm_widget *w; 1725 struct snd_soc_dapm_widget *w;
1726 unsigned int val;
1667 1727
1668 list_for_each_entry(w, &dapm->card->widgets, list) 1728 list_for_each_entry(w, &dapm->card->widgets, list)
1669 { 1729 {
@@ -1712,6 +1772,18 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1712 case snd_soc_dapm_post: 1772 case snd_soc_dapm_post:
1713 break; 1773 break;
1714 } 1774 }
1775
1776 /* Read the initial power state from the device */
1777 if (w->reg >= 0) {
1778 val = snd_soc_read(w->codec, w->reg);
1779 val &= 1 << w->shift;
1780 if (w->invert)
1781 val = !val;
1782
1783 if (val)
1784 w->power = 1;
1785 }
1786
1715 w->new = 1; 1787 w->new = 1;
1716 } 1788 }
1717 1789
@@ -2130,14 +2202,14 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2130 return -ENOMEM; 2202 return -ENOMEM;
2131 2203
2132 name_len = strlen(widget->name) + 1; 2204 name_len = strlen(widget->name) + 1;
2133 if (dapm->codec->name_prefix) 2205 if (dapm->codec && dapm->codec->name_prefix)
2134 name_len += 1 + strlen(dapm->codec->name_prefix); 2206 name_len += 1 + strlen(dapm->codec->name_prefix);
2135 w->name = kmalloc(name_len, GFP_KERNEL); 2207 w->name = kmalloc(name_len, GFP_KERNEL);
2136 if (w->name == NULL) { 2208 if (w->name == NULL) {
2137 kfree(w); 2209 kfree(w);
2138 return -ENOMEM; 2210 return -ENOMEM;
2139 } 2211 }
2140 if (dapm->codec->name_prefix) 2212 if (dapm->codec && dapm->codec->name_prefix)
2141 snprintf(w->name, name_len, "%s %s", 2213 snprintf(w->name, name_len, "%s %s",
2142 dapm->codec->name_prefix, widget->name); 2214 dapm->codec->name_prefix, widget->name);
2143 else 2215 else
@@ -2242,7 +2314,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2242 mutex_unlock(&codec->mutex); 2314 mutex_unlock(&codec->mutex);
2243 return 0; 2315 return 0;
2244} 2316}
2245EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
2246 2317
2247/** 2318/**
2248 * snd_soc_dapm_enable_pin - enable pin. 2319 * snd_soc_dapm_enable_pin - enable pin.
@@ -2419,9 +2490,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2419 * standby. 2490 * standby.
2420 */ 2491 */
2421 if (powerdown) { 2492 if (powerdown) {
2422 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); 2493 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE);
2423 dapm_seq_run(dapm, &down_list, 0, false); 2494 dapm_seq_run(dapm, &down_list, 0, false);
2424 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); 2495 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY);
2425 } 2496 }
2426} 2497}
2427 2498
@@ -2434,7 +2505,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
2434 2505
2435 list_for_each_entry(codec, &card->codec_dev_list, list) { 2506 list_for_each_entry(codec, &card->codec_dev_list, list) {
2436 soc_dapm_shutdown_codec(&codec->dapm); 2507 soc_dapm_shutdown_codec(&codec->dapm);
2437 snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF); 2508 snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF);
2438 } 2509 }
2439} 2510}
2440 2511
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index ac5a5bc7375a..fcab80b36a37 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
37{ 37{
38 jack->codec = codec; 38 jack->codec = codec;
39 INIT_LIST_HEAD(&jack->pins); 39 INIT_LIST_HEAD(&jack->pins);
40 INIT_LIST_HEAD(&jack->jack_zones);
40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 41 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
41 42
42 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack); 43 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
@@ -100,7 +101,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
100 } 101 }
101 102
102 /* Report before the DAPM sync to help users updating micbias status */ 103 /* Report before the DAPM sync to help users updating micbias status */
103 blocking_notifier_call_chain(&jack->notifier, status, NULL); 104 blocking_notifier_call_chain(&jack->notifier, status, jack);
104 105
105 snd_soc_dapm_sync(dapm); 106 snd_soc_dapm_sync(dapm);
106 107
@@ -112,6 +113,51 @@ out:
112EXPORT_SYMBOL_GPL(snd_soc_jack_report); 113EXPORT_SYMBOL_GPL(snd_soc_jack_report);
113 114
114/** 115/**
116 * snd_soc_jack_add_zones - Associate voltage zones with jack
117 *
118 * @jack: ASoC jack
119 * @count: Number of zones
120 * @zone: Array of zones
121 *
122 * After this function has been called the zones specified in the
123 * array will be associated with the jack.
124 */
125int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
126 struct snd_soc_jack_zone *zones)
127{
128 int i;
129
130 for (i = 0; i < count; i++) {
131 INIT_LIST_HEAD(&zones[i].list);
132 list_add(&(zones[i].list), &jack->jack_zones);
133 }
134 return 0;
135}
136EXPORT_SYMBOL_GPL(snd_soc_jack_add_zones);
137
138/**
139 * snd_soc_jack_get_type - Based on the mic bias value, this function returns
140 * the type of jack from the zones delcared in the jack type
141 *
142 * @micbias_voltage: mic bias voltage at adc channel when jack is plugged in
143 *
144 * Based on the mic bias value passed, this function helps identify
145 * the type of jack from the already delcared jack zones
146 */
147int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage)
148{
149 struct snd_soc_jack_zone *zone;
150
151 list_for_each_entry(zone, &jack->jack_zones, list) {
152 if (micbias_voltage >= zone->min_mv &&
153 micbias_voltage < zone->max_mv)
154 return zone->jack_type;
155 }
156 return 0;
157}
158EXPORT_SYMBOL_GPL(snd_soc_jack_get_type);
159
160/**
115 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack 161 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
116 * 162 *
117 * @jack: ASoC jack 163 * @jack: ASoC jack
@@ -194,7 +240,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
194 int enable; 240 int enable;
195 int report; 241 int report;
196 242
197 enable = gpio_get_value(gpio->gpio); 243 enable = gpio_get_value_cansleep(gpio->gpio);
198 if (gpio->invert) 244 if (gpio->invert)
199 enable = !enable; 245 enable = !enable;
200 246
@@ -284,6 +330,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
284 if (ret) 330 if (ret)
285 goto err; 331 goto err;
286 332
333 if (gpios[i].wake) {
334 ret = set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
335 if (ret != 0)
336 printk(KERN_ERR
337 "Failed to mark GPIO %d as wake source: %d\n",
338 gpios[i].gpio, ret);
339 }
340
287#ifdef CONFIG_GPIO_SYSFS 341#ifdef CONFIG_GPIO_SYSFS
288 /* Expose GPIO value over sysfs for diagnostic purposes */ 342 /* Expose GPIO value over sysfs for diagnostic purposes */
289 gpio_export(gpios[i].gpio, false); 343 gpio_export(gpios[i].gpio, false);
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index dfd2ab9d975c..fd183d3ab4f1 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -2,13 +2,14 @@
2snd-soc-tegra-das-objs := tegra_das.o 2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o 3snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o 4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-utils-objs += tegra_asoc_utils.o
5 6
7obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-utils.o
6obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o 8obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o
7obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o 9obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o
8obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o 10obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o
9 11
10# Tegra machine Support 12# Tegra machine Support
11snd-soc-tegra-harmony-objs := harmony.o 13snd-soc-tegra-harmony-objs := harmony.o
12snd-soc-tegra-harmony-objs += tegra_asoc_utils.o
13 14
14obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o 15obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
index 11e2cb825664..8585957477eb 100644
--- a/sound/soc/tegra/harmony.c
+++ b/sound/soc/tegra/harmony.c
@@ -38,10 +38,13 @@
38#include <mach/harmony_audio.h> 38#include <mach/harmony_audio.h>
39 39
40#include <sound/core.h> 40#include <sound/core.h>
41#include <sound/jack.h>
41#include <sound/pcm.h> 42#include <sound/pcm.h>
42#include <sound/pcm_params.h> 43#include <sound/pcm_params.h>
43#include <sound/soc.h> 44#include <sound/soc.h>
44 45
46#include "../codecs/wm8903.h"
47
45#include "tegra_das.h" 48#include "tegra_das.h"
46#include "tegra_i2s.h" 49#include "tegra_i2s.h"
47#include "tegra_pcm.h" 50#include "tegra_pcm.h"
@@ -49,10 +52,14 @@
49 52
50#define DRV_NAME "tegra-snd-harmony" 53#define DRV_NAME "tegra-snd-harmony"
51 54
55#define GPIO_SPKR_EN BIT(0)
56#define GPIO_INT_MIC_EN BIT(1)
57#define GPIO_EXT_MIC_EN BIT(2)
58
52struct tegra_harmony { 59struct tegra_harmony {
53 struct tegra_asoc_utils_data util_data; 60 struct tegra_asoc_utils_data util_data;
54 struct harmony_audio_platform_data *pdata; 61 struct harmony_audio_platform_data *pdata;
55 int gpio_spkr_en_requested; 62 int gpio_requested;
56}; 63};
57 64
58static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, 65static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
@@ -123,6 +130,33 @@ static struct snd_soc_ops harmony_asoc_ops = {
123 .hw_params = harmony_asoc_hw_params, 130 .hw_params = harmony_asoc_hw_params,
124}; 131};
125 132
133static struct snd_soc_jack harmony_hp_jack;
134
135static struct snd_soc_jack_pin harmony_hp_jack_pins[] = {
136 {
137 .pin = "Headphone Jack",
138 .mask = SND_JACK_HEADPHONE,
139 },
140};
141
142static struct snd_soc_jack_gpio harmony_hp_jack_gpios[] = {
143 {
144 .name = "headphone detect",
145 .report = SND_JACK_HEADPHONE,
146 .debounce_time = 150,
147 .invert = 1,
148 }
149};
150
151static struct snd_soc_jack harmony_mic_jack;
152
153static struct snd_soc_jack_pin harmony_mic_jack_pins[] = {
154 {
155 .pin = "Mic Jack",
156 .mask = SND_JACK_MICROPHONE,
157 },
158};
159
126static int harmony_event_int_spk(struct snd_soc_dapm_widget *w, 160static int harmony_event_int_spk(struct snd_soc_dapm_widget *w,
127 struct snd_kcontrol *k, int event) 161 struct snd_kcontrol *k, int event)
128{ 162{
@@ -154,6 +188,10 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = {
154 {"IN1L", NULL, "Mic Bias"}, 188 {"IN1L", NULL, "Mic Bias"},
155}; 189};
156 190
191static const struct snd_kcontrol_new harmony_controls[] = {
192 SOC_DAPM_PIN_SWITCH("Int Spk"),
193};
194
157static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) 195static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
158{ 196{
159 struct snd_soc_codec *codec = rtd->codec; 197 struct snd_soc_codec *codec = rtd->codec;
@@ -168,19 +206,65 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
168 dev_err(card->dev, "cannot get spkr_en gpio\n"); 206 dev_err(card->dev, "cannot get spkr_en gpio\n");
169 return ret; 207 return ret;
170 } 208 }
171 harmony->gpio_spkr_en_requested = 1; 209 harmony->gpio_requested |= GPIO_SPKR_EN;
172 210
173 gpio_direction_output(pdata->gpio_spkr_en, 0); 211 gpio_direction_output(pdata->gpio_spkr_en, 0);
174 212
213 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
214 if (ret) {
215 dev_err(card->dev, "cannot get int_mic_en gpio\n");
216 return ret;
217 }
218 harmony->gpio_requested |= GPIO_INT_MIC_EN;
219
220 /* Disable int mic; enable signal is active-high */
221 gpio_direction_output(pdata->gpio_int_mic_en, 0);
222
223 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
224 if (ret) {
225 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
226 return ret;
227 }
228 harmony->gpio_requested |= GPIO_EXT_MIC_EN;
229
230 /* Enable ext mic; enable signal is active-low */
231 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
232
233 ret = snd_soc_add_controls(codec, harmony_controls,
234 ARRAY_SIZE(harmony_controls));
235 if (ret < 0)
236 return ret;
237
175 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets, 238 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets,
176 ARRAY_SIZE(harmony_dapm_widgets)); 239 ARRAY_SIZE(harmony_dapm_widgets));
177 240
178 snd_soc_dapm_add_routes(dapm, harmony_audio_map, 241 snd_soc_dapm_add_routes(dapm, harmony_audio_map,
179 ARRAY_SIZE(harmony_audio_map)); 242 ARRAY_SIZE(harmony_audio_map));
180 243
181 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 244 harmony_hp_jack_gpios[0].gpio = pdata->gpio_hp_det;
182 snd_soc_dapm_enable_pin(dapm, "Int Spk"); 245 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
183 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 246 &harmony_hp_jack);
247 snd_soc_jack_add_pins(&harmony_hp_jack,
248 ARRAY_SIZE(harmony_hp_jack_pins),
249 harmony_hp_jack_pins);
250 snd_soc_jack_add_gpios(&harmony_hp_jack,
251 ARRAY_SIZE(harmony_hp_jack_gpios),
252 harmony_hp_jack_gpios);
253
254 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
255 &harmony_mic_jack);
256 snd_soc_jack_add_pins(&harmony_mic_jack,
257 ARRAY_SIZE(harmony_mic_jack_pins),
258 harmony_mic_jack_pins);
259 wm8903_mic_detect(codec, &harmony_mic_jack, SND_JACK_MICROPHONE, 0);
260
261 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
262
263 snd_soc_dapm_nc_pin(dapm, "IN3L");
264 snd_soc_dapm_nc_pin(dapm, "IN3R");
265 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
266 snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
267
184 snd_soc_dapm_sync(dapm); 268 snd_soc_dapm_sync(dapm);
185 269
186 return 0; 270 return 0;
@@ -189,7 +273,7 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
189static struct snd_soc_dai_link harmony_wm8903_dai = { 273static struct snd_soc_dai_link harmony_wm8903_dai = {
190 .name = "WM8903", 274 .name = "WM8903",
191 .stream_name = "WM8903 PCM", 275 .stream_name = "WM8903 PCM",
192 .codec_name = "wm8903-codec.0-001a", 276 .codec_name = "wm8903.0-001a",
193 .platform_name = "tegra-pcm-audio", 277 .platform_name = "tegra-pcm-audio",
194 .cpu_dai_name = "tegra-i2s.0", 278 .cpu_dai_name = "tegra-i2s.0",
195 .codec_dai_name = "wm8903-hifi", 279 .codec_dai_name = "wm8903-hifi",
@@ -270,7 +354,11 @@ static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev)
270 354
271 tegra_asoc_utils_fini(&harmony->util_data); 355 tegra_asoc_utils_fini(&harmony->util_data);
272 356
273 if (harmony->gpio_spkr_en_requested) 357 if (harmony->gpio_requested & GPIO_EXT_MIC_EN)
358 gpio_free(pdata->gpio_ext_mic_en);
359 if (harmony->gpio_requested & GPIO_INT_MIC_EN)
360 gpio_free(pdata->gpio_int_mic_en);
361 if (harmony->gpio_requested & GPIO_SPKR_EN)
274 gpio_free(pdata->gpio_spkr_en); 362 gpio_free(pdata->gpio_spkr_en);
275 363
276 kfree(harmony); 364 kfree(harmony);
@@ -302,3 +390,4 @@ module_exit(snd_tegra_harmony_exit);
302MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 390MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
303MODULE_DESCRIPTION("Harmony machine ASoC driver"); 391MODULE_DESCRIPTION("Harmony machine ASoC driver");
304MODULE_LICENSE("GPL"); 392MODULE_LICENSE("GPL");
393MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index cb4fc13c7d22..52f0a3f9ce40 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -101,6 +101,7 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
101 101
102 return 0; 102 return 0;
103} 103}
104EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
104 105
105int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, 106int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
106 struct device *dev) 107 struct device *dev)
@@ -139,6 +140,7 @@ err_put_pll_a:
139err: 140err:
140 return ret; 141 return ret;
141} 142}
143EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
142 144
143void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data) 145void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
144{ 146{
@@ -146,4 +148,8 @@ void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
146 clk_put(data->clk_pll_a_out0); 148 clk_put(data->clk_pll_a_out0);
147 clk_put(data->clk_pll_a); 149 clk_put(data->clk_pll_a);
148} 150}
151EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
149 152
153MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
154MODULE_DESCRIPTION("Tegra ASoC utility code");
155MODULE_LICENSE("GPL");
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
index 01eb9c9301de..9f24ef73f2cb 100644
--- a/sound/soc/tegra/tegra_das.c
+++ b/sound/soc/tegra/tegra_das.c
@@ -262,3 +262,4 @@ module_exit(tegra_das_modexit);
262MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 262MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
263MODULE_DESCRIPTION("Tegra DAS driver"); 263MODULE_DESCRIPTION("Tegra DAS driver");
264MODULE_LICENSE("GPL"); 264MODULE_LICENSE("GPL");
265MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 870ee361f757..4f5e2c90b020 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -500,3 +500,4 @@ module_exit(snd_tegra_i2s_exit);
500MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 500MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
501MODULE_DESCRIPTION("Tegra I2S ASoC driver"); 501MODULE_DESCRIPTION("Tegra I2S ASoC driver");
502MODULE_LICENSE("GPL"); 502MODULE_LICENSE("GPL");
503MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 663ea9fa0ca3..3c271f953582 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -39,6 +39,8 @@
39 39
40#include "tegra_pcm.h" 40#include "tegra_pcm.h"
41 41
42#define DRV_NAME "tegra-pcm-audio"
43
42static const struct snd_pcm_hardware tegra_pcm_hardware = { 44static const struct snd_pcm_hardware tegra_pcm_hardware = {
43 .info = SNDRV_PCM_INFO_MMAP | 45 .info = SNDRV_PCM_INFO_MMAP |
44 SNDRV_PCM_INFO_MMAP_VALID | 46 SNDRV_PCM_INFO_MMAP_VALID |
@@ -159,8 +161,8 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
159 prtd->dma_req[1].dev = prtd; 161 prtd->dma_req[1].dev = prtd;
160 162
161 prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT); 163 prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
162 if (IS_ERR(prtd->dma_chan)) { 164 if (prtd->dma_chan == NULL) {
163 ret = PTR_ERR(prtd->dma_chan); 165 ret = -ENOMEM;
164 goto err; 166 goto err;
165 } 167 }
166 168
@@ -377,7 +379,7 @@ static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev)
377 379
378static struct platform_driver tegra_pcm_driver = { 380static struct platform_driver tegra_pcm_driver = {
379 .driver = { 381 .driver = {
380 .name = "tegra-pcm-audio", 382 .name = DRV_NAME,
381 .owner = THIS_MODULE, 383 .owner = THIS_MODULE,
382 }, 384 },
383 .probe = tegra_pcm_platform_probe, 385 .probe = tegra_pcm_platform_probe,
@@ -399,3 +401,4 @@ module_exit(snd_tegra_pcm_exit);
399MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 401MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
400MODULE_DESCRIPTION("Tegra PCM ASoC driver"); 402MODULE_DESCRIPTION("Tegra PCM ASoC driver");
401MODULE_LICENSE("GPL"); 403MODULE_LICENSE("GPL");
404MODULE_ALIAS("platform:" DRV_NAME);