#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/control.h>
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
{ .max = xmax, .texts = xtexts }
+#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xmax, xtexts, xvalues) \
+{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
+ .mask = xmask, .max = xmax, .texts = xtexts, .values = xvalues}
+#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xmax, xtexts, xvalues) \
+ SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
#define SOC_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
.info = snd_soc_info_enum_double, \
.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
.private_value = (unsigned long)&xenum }
+#define SOC_VALUE_ENUM(xname, xenum) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
+ .info = snd_soc_info_enum_double, \
+ .get = snd_soc_get_value_enum_double, \
+ .put = snd_soc_put_value_enum_double, \
+ .private_value = (unsigned long)&xenum }
#define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
SND_SOC_BIAS_OFF,
};
+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_platform;
struct snd_soc_codec;
struct soc_enum;
struct snd_soc_ac97_ops;
-struct snd_soc_clock_info;
+struct snd_soc_jack;
+struct snd_soc_jack_pin;
+#ifdef CONFIG_GPIOLIB
+struct snd_soc_jack_gpio;
+#endif
typedef int (*hw_write_t)(void *,const char* ,int);
typedef int (*hw_read_t)(void *,char* ,int);
extern struct snd_ac97_bus_ops soc_ac97_ops;
+int snd_soc_register_platform(struct snd_soc_platform *platform);
+void snd_soc_unregister_platform(struct snd_soc_platform *platform);
+int snd_soc_register_codec(struct snd_soc_codec *codec);
+void snd_soc_unregister_codec(struct snd_soc_codec *codec);
+
/* pcm <-> DAI connect */
void snd_soc_free_pcms(struct snd_soc_device *socdev);
int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw);
+/* Jack reporting */
+int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
+ struct snd_soc_jack *jack);
+void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
+int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
+ struct snd_soc_jack_pin *pins);
+#ifdef CONFIG_GPIOLIB
+int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
+ struct snd_soc_jack_gpio *gpios);
+void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
+ struct snd_soc_jack_gpio *gpios);
+#endif
+
/* codec IO */
#define snd_soc_read(codec, reg) codec->read(codec, reg)
#define snd_soc_write(codec, reg, value) codec->write(codec, reg, value)
*/
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
void *data, char *long_name);
+int snd_soc_add_controls(struct snd_soc_codec *codec,
+ const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+/**
+ * struct snd_soc_jack_pin - Describes a pin to update based on jack detection
+ *
+ * @pin: name of the pin to update
+ * @mask: bits to check for in reported jack status
+ * @invert: if non-zero then pin is enabled when status is not reported
+ */
+struct snd_soc_jack_pin {
+ struct list_head list;
+ const char *pin;
+ int mask;
+ bool invert;
+};
+
+/**
+ * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection
+ *
+ * @gpio: gpio number
+ * @name: gpio name
+ * @report: value to report when jack detected
+ * @invert: report presence in low state
+ * @debouce_time: debouce time in ms
+ */
+#ifdef CONFIG_GPIOLIB
+struct snd_soc_jack_gpio {
+ unsigned int gpio;
+ const char *name;
+ int report;
+ int invert;
+ int debounce_time;
+ struct snd_soc_jack *jack;
+ struct work_struct work;
+};
+#endif
+
+struct snd_soc_jack {
+ struct snd_jack *jack;
+ struct snd_soc_card *card;
+ struct list_head pins;
+ int status;
+};
+
/* SoC PCM stream information */
struct snd_soc_pcm_stream {
char *stream_name;
char *name;
struct module *owner;
struct mutex mutex;
+ struct device *dev;
+
+ struct list_head list;
/* callbacks */
int (*set_bias_level)(struct snd_soc_codec *,
/* codec DAI's */
struct snd_soc_dai *dai;
unsigned int num_dai;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_reg;
+ struct dentry *debugfs_pop_time;
+#endif
};
/* codec device */
/* SoC platform interface */
struct snd_soc_platform {
char *name;
+ struct list_head list;
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
- int (*suspend)(struct platform_device *pdev,
- struct snd_soc_dai *dai);
- int (*resume)(struct platform_device *pdev,
- struct snd_soc_dai *dai);
+ int (*suspend)(struct snd_soc_dai *dai);
+ int (*resume)(struct snd_soc_dai *dai);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
/* SoC card */
struct snd_soc_card {
char *name;
+ struct device *dev;
+
+ struct list_head list;
+
+ int instantiated;
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link;
int num_links;
+
+ struct snd_soc_device *socdev;
+
+ struct snd_soc_codec *codec;
+
+ struct snd_soc_platform *platform;
+ struct delayed_work delayed_work;
+ struct work_struct deferred_resume_work;
};
/* SoC Device - the audio subsystem */
struct snd_soc_device {
struct device *dev;
struct snd_soc_card *card;
- struct snd_soc_platform *platform;
- struct snd_soc_codec *codec;
struct snd_soc_codec_device *codec_dev;
- struct delayed_work delayed_work;
- struct work_struct deferred_resume_work;
void *codec_data;
-#ifdef CONFIG_DEBUG_FS
- struct dentry *debugfs_root;
-#endif
};
/* runtime channel data */
unsigned char shift_l;
unsigned char shift_r;
unsigned int max;
+ unsigned int mask;
const char **texts;
+ const unsigned int *values;
void *dapm;
};