Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f4019e6 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/component' into asoc-next

parents 228704bb 4da53393
Loading
Loading
Loading
Loading
+107 −0
Original line number Diff line number Diff line
STA350 audio CODEC

The driver for this device only supports I2C.

Required properties:

  - compatible: "st,sta350"
  - reg: the I2C address of the device for I2C
  - reset-gpios: a GPIO spec for the reset pin. If specified, it will be
		 deasserted before communication to the codec starts.

  - power-down-gpios: a GPIO spec for the power down pin. If specified,
		      it will be deasserted before communication to the codec
		      starts.

  - vdd-dig-supply: regulator spec, providing 3.3V
  - vdd-pll-supply: regulator spec, providing 3.3V
  - vcc-supply: regulator spec, providing 5V - 26V

Optional properties:

  -  st,output-conf: number, Selects the output configuration:
	0: 2-channel (full-bridge) power, 2-channel data-out
	1: 2 (half-bridge). 1 (full-bridge) on-board power
	2: 2 Channel (Full-Bridge) Power, 1 Channel FFX
	3: 1 Channel Mono-Parallel
	If parameter is missing, mode 0 will be enabled.

  -  st,ch1-output-mapping: Channel 1 output mapping
  -  st,ch2-output-mapping: Channel 2 output mapping
  -  st,ch3-output-mapping: Channel 3 output mapping
	0: Channel 1
	1: Channel 2
	2: Channel 3
	If parameter is missing, channel 1 is choosen.

  -  st,thermal-warning-recover:
	If present, thermal warning recovery is enabled.

  -  st,thermal-warning-adjustment:
	If present, thermal warning adjustment is enabled.

  -  st,fault-detect-recovery:
	If present, then fault recovery will be enabled.

  -  st,ffx-power-output-mode: string
	The FFX power output mode selects how the FFX output timing is
	configured. Must be one of these values:
	  -  "drop-compensation"
	  -  "tapered-compensation"
	  -  "full-power-mode"
	  -  "variable-drop-compensation" (default)

  -  st,drop-compensation-ns: number
	Only required for "st,ffx-power-output-mode" ==
	"variable-drop-compensation".
	Specifies the drop compensation in nanoseconds.
	The value must be in the range of 0..300, and only
	multiples of 20 are allowed. Default is 140ns.

  -  st,overcurrent-warning-adjustment:
	If present, overcurrent warning adjustment is enabled.

  -  st,max-power-use-mpcc:
	If present, then MPCC bits are used for MPC coefficients,
	otherwise standard MPC coefficients are used.

  -  st,max-power-corr:
	If present, power bridge correction for THD reduction near maximum
	power output is enabled.

  -  st,am-reduction-mode:
	If present, FFX mode runs in AM reduction mode, otherwise normal
	FFX mode is used.

  -  st,odd-pwm-speed-mode:
	If present, PWM speed mode run on odd speed mode (341.3 kHz) on all
	channels. If not present, normal PWM spped mode (384 kHz) will be used.

  -  st,distortion-compensation:
	If present, distortion compensation variable uses DCC coefficient.
	If not present, preset DC coefficient is used.

  -  st,invalid-input-detect-mute:
	If not present, automatic invalid input detect mute is enabled.



Example:

codec: sta350@38 {
	compatible = "st,sta350";
	reg = <0x1c>;
	reset-gpios = <&gpio1 19 0>;
	power-down-gpios = <&gpio1 16 0>;
	st,output-conf = <0x3>;			// set output to 2-channel
						// (full-bridge) power,
						// 2-channel data-out
	st,ch1-output-mapping = <0>;		// set channel 1 output ch 1
	st,ch2-output-mapping = <0>;		// set channel 2 output ch 1
	st,ch3-output-mapping = <0>;		// set channel 3 output ch 1
	st,max-power-correction;		// enables power bridge
						// correction for THD reduction
						// near maximum power output
	st,invalid-input-detect-mute;		// mute if no valid digital
						// audio signal is provided.
};
+1 −0
Original line number Diff line number Diff line
@@ -606,6 +606,7 @@ struct snd_soc_dapm_context {
			     enum snd_soc_dapm_type, int);

	struct device *dev; /* from parent - for debug */
	struct snd_soc_component *component; /* parent component */
	struct snd_soc_codec *codec; /* parent codec */
	struct snd_soc_platform *platform; /* parent platform */
	struct snd_soc_card *card; /* parent card */
+91 −26
Original line number Diff line number Diff line
@@ -393,14 +393,6 @@ int devm_snd_soc_register_component(struct device *dev,
			 const struct snd_soc_component_driver *cmpnt_drv,
			 struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_component(struct device *dev);
int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
				    unsigned int reg);
int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
				    unsigned int reg);
int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
				    unsigned int reg);
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
			       struct regmap *regmap);
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);
@@ -469,12 +461,12 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
#endif

/* codec register bit access */
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
				unsigned int mask, unsigned int value);
int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
			       unsigned short reg, unsigned int mask,
			       unsigned int reg, unsigned int mask,
			       unsigned int value);
int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
				unsigned int mask, unsigned int value);

int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
@@ -668,6 +660,7 @@ struct snd_soc_component {
	unsigned int active;

	unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
	unsigned int registered_as_component:1;

	struct list_head list;

@@ -677,6 +670,14 @@ struct snd_soc_component {
	const struct snd_soc_component_driver *driver;

	struct list_head dai_list;

	int (*read)(struct snd_soc_component *, unsigned int, unsigned int *);
	int (*write)(struct snd_soc_component *, unsigned int, unsigned int);

	struct regmap *regmap;
	int val_bytes;

	struct mutex io_mutex;
};

/* SoC Audio Codec device */
@@ -692,9 +693,6 @@ struct snd_soc_codec {
	struct list_head list;
	struct list_head card_list;
	int num_dai;
	int (*volatile_register)(struct snd_soc_codec *, unsigned int);
	int (*readable_register)(struct snd_soc_codec *, unsigned int);
	int (*writable_register)(struct snd_soc_codec *, unsigned int);

	/* runtime */
	struct snd_ac97 *ac97;  /* for ad-hoc ac97 devices */
@@ -704,18 +702,14 @@ 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 cache_init:1; /* codec cache has been initialized */
	unsigned int using_regmap:1; /* using regmap access */
	u32 cache_only;  /* Suppress writes to hardware */
	u32 cache_sync; /* Cache needs to be synced to hardware */

	/* codec IO */
	void *control_data; /* codec control (i2c/3wire) data */
	hw_write_t hw_write;
	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
	int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
	void *reg_cache;
	struct mutex cache_rw_mutex;
	int val_bytes;

	/* component */
	struct snd_soc_component component;
@@ -754,13 +748,9 @@ struct snd_soc_codec_driver {
		unsigned int freq_in, unsigned int freq_out);

	/* codec IO */
	struct regmap *(*get_regmap)(struct device *);
	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
	int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
	int (*display_register)(struct snd_soc_codec *, char *,
				size_t, unsigned int);
	int (*volatile_register)(struct snd_soc_codec *, unsigned int);
	int (*readable_register)(struct snd_soc_codec *, unsigned int);
	int (*writable_register)(struct snd_soc_codec *, unsigned int);
	unsigned int reg_cache_size;
	short reg_cache_step;
	short reg_word_size;
@@ -791,6 +781,7 @@ struct snd_soc_platform_driver {
	int (*remove)(struct snd_soc_platform *);
	int (*suspend)(struct snd_soc_dai *dai);
	int (*resume)(struct snd_soc_dai *dai);
	struct snd_soc_component_driver component_driver;

	/* pcm creation and destruction */
	int (*pcm_new)(struct snd_soc_pcm_runtime *);
@@ -835,7 +826,6 @@ struct snd_soc_platform {
	int id;
	struct device *dev;
	const struct snd_soc_platform_driver *driver;
	struct mutex mutex;

	unsigned int suspended:1; /* platform is suspended */
	unsigned int probed:1;
@@ -844,6 +834,8 @@ struct snd_soc_platform {
	struct list_head list;
	struct list_head card_list;

	struct snd_soc_component component;

	struct snd_soc_dapm_context dapm;

#ifdef CONFIG_DEBUG_FS
@@ -1120,10 +1112,39 @@ static inline struct snd_soc_codec *snd_soc_component_to_codec(
	return container_of(component, struct snd_soc_codec, component);
}

/**
 * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in
 * @component: The component to cast to a platform
 *
 * This function must only be used on components that are known to be platforms.
 * Otherwise the behavior is undefined.
 */
static inline struct snd_soc_platform *snd_soc_component_to_platform(
	struct snd_soc_component *component)
{
	return container_of(component, struct snd_soc_platform, component);
}

/* codec IO */
unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
unsigned int snd_soc_write(struct snd_soc_codec *codec,
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
	unsigned int val);

/* component IO */
int snd_soc_component_read(struct snd_soc_component *component,
	unsigned int reg, unsigned int *val);
int snd_soc_component_write(struct snd_soc_component *component,
	unsigned int reg, unsigned int val);
int snd_soc_component_update_bits(struct snd_soc_component *component,
	unsigned int reg, unsigned int mask, unsigned int val);
int snd_soc_component_update_bits_async(struct snd_soc_component *component,
	unsigned int reg, unsigned int mask, unsigned int val);
void snd_soc_component_async_complete(struct snd_soc_component *component);
int snd_soc_component_test_bits(struct snd_soc_component *component,
	unsigned int reg, unsigned int mask, unsigned int value);

int snd_soc_component_init_io(struct snd_soc_component *component,
	struct regmap *regmap);

/* device driver data */

@@ -1228,6 +1249,50 @@ static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
	return snd_soc_component_is_active(&codec->component);
}

/**
 * snd_soc_kcontrol_component() - Returns the component that registered the
 *  control
 * @kcontrol: The control for which to get the component
 *
 * Note: This function will work correctly if the control has been registered
 * for a component. Either with snd_soc_add_codec_controls() or
 * snd_soc_add_platform_controls() or via  table based setup for either a
 * CODEC, a platform or component driver. Otherwise the behavior is undefined.
 */
static inline struct snd_soc_component *snd_soc_kcontrol_component(
	struct snd_kcontrol *kcontrol)
{
	return snd_kcontrol_chip(kcontrol);
}

/**
 * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control
 * @kcontrol: The control for which to get the CODEC
 *
 * Note: This function will only work correctly if the control has been
 * registered with snd_soc_add_codec_controls() or via table based setup of
 * snd_soc_codec_driver. Otherwise the behavior is undefined.
 */
static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
	struct snd_kcontrol *kcontrol)
{
	return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol));
}

/**
 * snd_soc_kcontrol_platform() - Returns the platform that registerd the control
 * @kcontrol: The control for which to get the platform
 *
 * Note: This function will only work correctly if the control has been
 * registered with snd_soc_add_platform_controls() or via table based setup of
 * a snd_soc_platform_driver. Otherwise the behavior is undefined.
 */
static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
	struct snd_kcontrol *kcontrol)
{
	return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol));
}

int snd_soc_util_init(void);
void snd_soc_util_exit(void);

include/sound/sta350.h

0 → 100644
+52 −0
Original line number Diff line number Diff line
/*
 * Platform data for ST STA350 ASoC codec driver.
 *
 * Copyright: 2014 Raumfeld GmbH
 * Author: Sven Brandau <info@brandau.biz>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */
#ifndef __LINUX_SND__STA350_H
#define __LINUX_SND__STA350_H

#define STA350_OCFG_2CH		0
#define STA350_OCFG_2_1CH	1
#define STA350_OCFG_1CH		3

#define STA350_OM_CH1		0
#define STA350_OM_CH2		1
#define STA350_OM_CH3		2

#define STA350_THERMAL_ADJUSTMENT_ENABLE	1
#define STA350_THERMAL_RECOVERY_ENABLE		2
#define STA350_FAULT_DETECT_RECOVERY_BYPASS	1

#define STA350_FFX_PM_DROP_COMP			0
#define STA350_FFX_PM_TAPERED_COMP		1
#define STA350_FFX_PM_FULL_POWER		2
#define STA350_FFX_PM_VARIABLE_DROP_COMP	3


struct sta350_platform_data {
	u8 output_conf;
	u8 ch1_output_mapping;
	u8 ch2_output_mapping;
	u8 ch3_output_mapping;
	u8 ffx_power_output_mode;
	u8 drop_compensation_ns;
	unsigned int thermal_warning_recovery:1;
	unsigned int thermal_warning_adjustment:1;
	unsigned int fault_detect_recovery:1;
	unsigned int oc_warning_adjustment:1;
	unsigned int max_power_use_mpcc:1;
	unsigned int max_power_correction:1;
	unsigned int am_reduction_mode:1;
	unsigned int odd_pwm_speed_mode:1;
	unsigned int distortion_compensation:1;
	unsigned int invalid_input_detect_mute:1;
};

#endif /* __LINUX_SND__STA350_H */
+0 −92
Original line number Diff line number Diff line
@@ -11,102 +11,10 @@

struct snd_soc_jack;
struct snd_soc_codec;
struct snd_soc_platform;
struct snd_soc_card;
struct snd_soc_dapm_widget;
struct snd_soc_dapm_path;

/*
 * Log register events
 */
DECLARE_EVENT_CLASS(snd_soc_reg,

	TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
		 unsigned int val),

	TP_ARGS(codec, reg, val),

	TP_STRUCT__entry(
		__string(	name,		codec->name	)
		__field(	int,		id		)
		__field(	unsigned int,	reg		)
		__field(	unsigned int,	val		)
	),

	TP_fast_assign(
		__assign_str(name, codec->name);
		__entry->id = codec->id;
		__entry->reg = reg;
		__entry->val = val;
	),

	TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name),
		  (int)__entry->id, (unsigned int)__entry->reg,
		  (unsigned int)__entry->val)
);

DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write,

	TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
		 unsigned int val),

	TP_ARGS(codec, reg, val)

);

DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read,

	TP_PROTO(struct snd_soc_codec *codec, unsigned int reg,
		 unsigned int val),

	TP_ARGS(codec, reg, val)

);

DECLARE_EVENT_CLASS(snd_soc_preg,

	TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
		 unsigned int val),

	TP_ARGS(platform, reg, val),

	TP_STRUCT__entry(
		__string(	name,		platform->name	)
		__field(	int,		id		)
		__field(	unsigned int,	reg		)
		__field(	unsigned int,	val		)
	),

	TP_fast_assign(
		__assign_str(name, platform->name);
		__entry->id = platform->id;
		__entry->reg = reg;
		__entry->val = val;
	),

	TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name),
		  (int)__entry->id, (unsigned int)__entry->reg,
		  (unsigned int)__entry->val)
);

DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write,

	TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
		 unsigned int val),

	TP_ARGS(platform, reg, val)

);

DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read,

	TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
		 unsigned int val),

	TP_ARGS(platform, reg, val)

);

DECLARE_EVENT_CLASS(snd_soc_card,

	TP_PROTO(struct snd_soc_card *card, int val),
Loading