diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-01-13 08:37:24 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-01-13 08:37:24 +0100 |
commit | 6db9a0f326d3144d790d9479309df480a8f562e4 (patch) | |
tree | 650a8950c35c087278ecee1b8d123f75f601ebc8 /include/sound | |
parent | c400c9e23feb5bb3fbe8a8d4581ecce3b19a2f38 (diff) | |
parent | 18b022eb117e7f70c191267551ff865f278a9258 (diff) | |
download | linux-6db9a0f326d3144d790d9479309df480a8f562e4.tar.bz2 |
Merge branch 'topic/asoc' into for-linus
Diffstat (limited to 'include/sound')
-rw-r--r-- | include/sound/alc5623.h | 15 | ||||
-rw-r--r-- | include/sound/soc-dai.h | 4 | ||||
-rw-r--r-- | include/sound/soc-dapm.h | 99 | ||||
-rw-r--r-- | include/sound/soc.h | 116 |
4 files changed, 177 insertions, 57 deletions
diff --git a/include/sound/alc5623.h b/include/sound/alc5623.h new file mode 100644 index 000000000000..422c97d43df3 --- /dev/null +++ b/include/sound/alc5623.h @@ -0,0 +1,15 @@ +#ifndef _INCLUDE_SOUND_ALC5623_H +#define _INCLUDE_SOUND_ALC5623_H +struct alc5623_platform_data { + /* configure : */ + /* Lineout/Speaker Amps Vmid ratio control */ + /* enable/disable adc/dac high pass filters */ + unsigned int add_ctrl; + /* configure : */ + /* output to enable when jack is low */ + /* output to enable when jack is high */ + /* jack detect (gpio/nc/jack detect [12] */ + unsigned int jack_det_ctrl; +}; +#endif + diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index e7b680248006..1bafe95dcf41 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -16,8 +16,6 @@ #include <linux/list.h> -#include <sound/soc.h> - struct snd_pcm_substream; /* @@ -205,7 +203,7 @@ struct snd_soc_dai_driver { int (*resume)(struct snd_soc_dai *dai); /* ops */ - struct snd_soc_dai_ops *ops; + const struct snd_soc_dai_ops *ops; /* DAI capabilities */ struct snd_soc_pcm_stream capture; diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 8fd3b41b763f..8031769ac485 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -16,7 +16,6 @@ #include <linux/device.h> #include <linux/types.h> #include <sound/control.h> -#include <sound/soc.h> /* widget has no PM register bit */ #define SND_SOC_NOPM -1 @@ -72,6 +71,10 @@ wcontrols, wncontrols) \ { .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} +#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\ + wcontrols, wncontrols) \ +{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} #define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \ wcontrols, wncontrols)\ { .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ @@ -90,6 +93,9 @@ #define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \ { .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} +#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \ +{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} #define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \ { .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \ .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ @@ -116,6 +122,11 @@ { .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ .event = wevent, .event_flags = wflags} +#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \ + wncontrols, wevent, wflags) \ +{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ + .event = wevent, .event_flags = wflags} #define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \ wncontrols, wevent, wflags) \ { .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ @@ -140,6 +151,11 @@ { .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ .event = wevent, .event_flags = wflags} +#define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ + wevent, wflags) \ +{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ + .event = wevent, .event_flags = wflags} /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ #define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ @@ -219,13 +235,6 @@ .info = snd_soc_info_volsw, \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } -#define SOC_DAPM_DOUBLE(xname, reg, shift_left, shift_right, max, invert, \ - power) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\ - ((max) << 16) | ((invert) << 24) } #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ @@ -233,15 +242,6 @@ .tlv.p = (tlv_array), \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } -#define SOC_DAPM_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, \ - power, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\ - ((max) << 16) | ((invert) << 24) } #define SOC_DAPM_ENUM(xname, xenum) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_enum_double, \ @@ -297,6 +297,7 @@ enum snd_soc_dapm_type; struct snd_soc_dapm_path; struct snd_soc_dapm_pin; struct snd_soc_dapm_route; +struct snd_soc_dapm_context; int dapm_reg_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); @@ -324,16 +325,16 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol); int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol); -int snd_soc_dapm_new_control(struct snd_soc_codec *codec, +int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget); -int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, +int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget, int num); /* dapm path setup */ -int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); -void snd_soc_dapm_free(struct snd_soc_codec *codec); -int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, +int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm); +void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); +int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route, int num); /* dapm events */ @@ -343,27 +344,33 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card); /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); -void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec); +void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm); /* dapm audio pin control and status */ -int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_sync(struct snd_soc_codec *codec); -int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, +int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, + const char *pin); +int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, + const char *pin); +int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); +int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, + const char *pin); +int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); +int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin); -int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin); +int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, + const char *pin); /* dapm widget types */ enum snd_soc_dapm_type { snd_soc_dapm_input = 0, /* input pin */ snd_soc_dapm_output, /* output pin */ snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */ + snd_soc_dapm_virt_mux, /* virtual version of snd_soc_dapm_mux */ snd_soc_dapm_value_mux, /* selects 1 analog signal from many inputs */ snd_soc_dapm_mixer, /* mixes several analog signals together */ snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */ snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */ + snd_soc_dapm_out_drv, /* output driver */ snd_soc_dapm_adc, /* analog to digital converter */ snd_soc_dapm_dac, /* digital to analog converter */ snd_soc_dapm_micbias, /* microphone bias (power) */ @@ -425,6 +432,7 @@ struct snd_soc_dapm_widget { char *sname; /* stream name */ struct snd_soc_codec *codec; struct list_head list; + struct snd_soc_dapm_context *dapm; /* dapm control */ short reg; /* negative reg = no direct dapm */ @@ -461,4 +469,35 @@ struct snd_soc_dapm_widget { struct list_head power_list; }; +struct snd_soc_dapm_update { + struct snd_soc_dapm_widget *widget; + struct snd_kcontrol *kcontrol; + int reg; + int mask; + int val; +}; + +/* DAPM context */ +struct snd_soc_dapm_context { + int n_widgets; /* number of widgets in this context */ + enum snd_soc_bias_level bias_level; + enum snd_soc_bias_level suspend_bias_level; + struct delayed_work delayed_work; + unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ + + struct snd_soc_dapm_update *update; + + struct device *dev; /* from parent - for debug */ + struct snd_soc_codec *codec; /* parent codec */ + struct snd_soc_card *card; /* parent card */ + + /* used during DAPM updates */ + int dev_power; + struct list_head list; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dapm; +#endif +}; + #endif diff --git a/include/sound/soc.h b/include/sound/soc.h index 5c3bce83f28a..74921f20a1d8 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -222,10 +222,8 @@ enum snd_soc_bias_level { struct snd_jack; struct snd_soc_card; -struct snd_soc_device; struct snd_soc_pcm_stream; struct snd_soc_ops; -struct snd_soc_dai_mode; struct snd_soc_pcm_runtime; struct snd_soc_dai; struct snd_soc_dai_driver; @@ -235,9 +233,10 @@ struct snd_soc_platform_driver; struct snd_soc_codec; struct snd_soc_codec_driver; struct soc_enum; -struct snd_soc_ac97_ops; struct snd_soc_jack; struct snd_soc_jack_pin; +struct snd_soc_cache_ops; +#include <sound/soc-dapm.h> #ifdef CONFIG_GPIOLIB struct snd_soc_jack_gpio; @@ -253,17 +252,30 @@ enum snd_soc_control_type { SND_SOC_SPI, }; +enum snd_soc_compress_type { + SND_SOC_FLAT_COMPRESSION = 1, + SND_SOC_LZO_COMPRESSION, + SND_SOC_RBTREE_COMPRESSION +}; + int snd_soc_register_platform(struct device *dev, struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); int snd_soc_register_codec(struct device *dev, - struct snd_soc_codec_driver *codec_drv, + const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_codec(struct device *dev); int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg); int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, int addr_bits, int data_bits, enum snd_soc_control_type control); +int snd_soc_cache_sync(struct snd_soc_codec *codec); +int snd_soc_cache_init(struct snd_soc_codec *codec); +int snd_soc_cache_exit(struct snd_soc_codec *codec); +int snd_soc_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value); +int snd_soc_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value); /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); @@ -420,23 +432,37 @@ struct snd_soc_ops { int (*trigger)(struct snd_pcm_substream *, int); }; +/* SoC cache ops */ +struct snd_soc_cache_ops { + const char *name; + enum snd_soc_compress_type id; + int (*init)(struct snd_soc_codec *codec); + int (*exit)(struct snd_soc_codec *codec); + int (*read)(struct snd_soc_codec *codec, unsigned int reg, + unsigned int *value); + int (*write)(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value); + int (*sync)(struct snd_soc_codec *codec); +}; + /* SoC Audio Codec device */ struct snd_soc_codec { const char *name; + const char *name_prefix; int id; struct device *dev; - struct snd_soc_codec_driver *driver; + const struct snd_soc_codec_driver *driver; struct mutex mutex; struct snd_soc_card *card; struct list_head list; struct list_head card_list; int num_dai; + enum snd_soc_compress_type compress_type; /* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ unsigned int active; - unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ unsigned int cache_only:1; /* Suppress writes to hardware */ unsigned int cache_sync:1; /* Cache needs to be synced to hardware */ unsigned int suspended:1; /* Codec is in suspend PM state */ @@ -444,25 +470,25 @@ struct snd_soc_codec { unsigned int ac97_registered:1; /* Codec has been AC97 registered */ unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int sysfs_registered:1; /* codec has been sysfs registered */ + unsigned int cache_init:1; /* codec cache has been initialized */ /* codec IO */ void *control_data; /* codec control (i2c/3wire) data */ hw_write_t hw_write; unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); + unsigned int (*read)(struct snd_soc_codec *, unsigned int); + int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); void *reg_cache; + const void *reg_def_copy; + const struct snd_soc_cache_ops *cache_ops; + struct mutex cache_rw_mutex; /* dapm */ - u32 pop_time; - struct list_head dapm_widgets; - struct list_head dapm_paths; - enum snd_soc_bias_level bias_level; - enum snd_soc_bias_level suspend_bias_level; - struct delayed_work delayed_work; + struct snd_soc_dapm_context dapm; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_codec_root; struct dentry *debugfs_reg; - struct dentry *debugfs_pop_time; struct dentry *debugfs_dapm; #endif }; @@ -488,6 +514,7 @@ struct snd_soc_codec_driver { short reg_cache_step; short reg_word_size; const void *reg_cache_default; + enum snd_soc_compress_type compress_type; /* codec bias level */ int (*set_bias_level)(struct snd_soc_codec *, @@ -554,6 +581,30 @@ struct snd_soc_dai_link { struct snd_soc_ops *ops; }; +struct snd_soc_codec_conf { + const char *dev_name; + + /* + * optional map of kcontrol, widget and path name prefixes that are + * associated per device + */ + const char *name_prefix; + + /* + * set this to the desired compression type if you want to + * override the one supplied in codec->driver->compress_type + */ + enum snd_soc_compress_type compress_type; +}; + +struct snd_soc_aux_dev { + const char *name; /* Codec name */ + const char *codec_name; /* for multi-codec */ + + /* codec/machine specific init - e.g. add machine controls */ + int (*init)(struct snd_soc_dapm_context *dapm); +}; + /* SoC card */ struct snd_soc_card { const char *name; @@ -579,6 +630,8 @@ struct snd_soc_card { /* callbacks */ int (*set_bias_level)(struct snd_soc_card *, enum snd_soc_bias_level level); + int (*set_bias_level_post)(struct snd_soc_card *, + enum snd_soc_bias_level level); long pmdown_time; @@ -588,12 +641,35 @@ struct snd_soc_card { struct snd_soc_pcm_runtime *rtd; int num_rtd; + /* optional codec specific configuration */ + struct snd_soc_codec_conf *codec_conf; + int num_configs; + + /* + * optional auxiliary devices such as amplifiers or codecs with DAI + * link unused + */ + struct snd_soc_aux_dev *aux_dev; + int num_aux_devs; + struct snd_soc_pcm_runtime *rtd_aux; + int num_aux_rtd; + struct work_struct deferred_resume_work; /* lists of probed devices belonging to this card */ struct list_head codec_dev_list; struct list_head platform_dev_list; struct list_head dai_dev_list; + + struct list_head widgets; + struct list_head paths; + struct list_head dapm_list; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_card_root; + struct dentry *debugfs_pop_time; +#endif + u32 pop_time; }; /* SoC machine DAI configuration, glues a codec and cpu DAI together */ @@ -639,17 +715,9 @@ struct soc_enum { }; /* codec IO */ -static inline unsigned int snd_soc_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return codec->driver->read(codec, reg); -} - -static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val) -{ - return codec->driver->write(codec, reg, val); -} +unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); +unsigned int snd_soc_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val); /* device driver data */ |