brintos

brintos / linux-shallow public Read only

0
0
Text · 36.4 KiB · d1450de Raw
1261 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system4 *5 * Copyright: 2014 Raumfeld GmbH6 * Author: Sven Brandau <info@brandau.biz>7 *8 * based on code from:9 *	Raumfeld GmbH10 *	  Johannes Stezenbach <js@sig21.net>11 *	Wolfson Microelectronics PLC.12 *	  Mark Brown <broonie@opensource.wolfsonmicro.com>13 *	Freescale Semiconductor, Inc.14 *	  Timur Tabi <timur@freescale.com>15 */16 17#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__18 19#include <linux/module.h>20#include <linux/moduleparam.h>21#include <linux/init.h>22#include <linux/delay.h>23#include <linux/pm.h>24#include <linux/i2c.h>25#include <linux/of.h>26#include <linux/regmap.h>27#include <linux/regulator/consumer.h>28#include <linux/gpio/consumer.h>29#include <linux/slab.h>30#include <sound/core.h>31#include <sound/pcm.h>32#include <sound/pcm_params.h>33#include <sound/soc.h>34#include <sound/soc-dapm.h>35#include <sound/initval.h>36#include <sound/tlv.h>37 38#include <sound/sta350.h>39#include "sta350.h"40 41#define STA350_RATES (SNDRV_PCM_RATE_32000 | \42		      SNDRV_PCM_RATE_44100 | \43		      SNDRV_PCM_RATE_48000 | \44		      SNDRV_PCM_RATE_88200 | \45		      SNDRV_PCM_RATE_96000 | \46		      SNDRV_PCM_RATE_176400 | \47		      SNDRV_PCM_RATE_192000)48 49#define STA350_FORMATS \50	(SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S18_3LE | \51	 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_3LE | \52	 SNDRV_PCM_FMTBIT_S24_LE  | SNDRV_PCM_FMTBIT_S32_LE)53 54/* Power-up register defaults */55static const struct reg_default sta350_regs[] = {56	{  0x0, 0x63 },57	{  0x1, 0x80 },58	{  0x2, 0xdf },59	{  0x3, 0x40 },60	{  0x4, 0xc2 },61	{  0x5, 0x5c },62	{  0x6, 0x00 },63	{  0x7, 0xff },64	{  0x8, 0x60 },65	{  0x9, 0x60 },66	{  0xa, 0x60 },67	{  0xb, 0x00 },68	{  0xc, 0x00 },69	{  0xd, 0x00 },70	{  0xe, 0x00 },71	{  0xf, 0x40 },72	{ 0x10, 0x80 },73	{ 0x11, 0x77 },74	{ 0x12, 0x6a },75	{ 0x13, 0x69 },76	{ 0x14, 0x6a },77	{ 0x15, 0x69 },78	{ 0x16, 0x00 },79	{ 0x17, 0x00 },80	{ 0x18, 0x00 },81	{ 0x19, 0x00 },82	{ 0x1a, 0x00 },83	{ 0x1b, 0x00 },84	{ 0x1c, 0x00 },85	{ 0x1d, 0x00 },86	{ 0x1e, 0x00 },87	{ 0x1f, 0x00 },88	{ 0x20, 0x00 },89	{ 0x21, 0x00 },90	{ 0x22, 0x00 },91	{ 0x23, 0x00 },92	{ 0x24, 0x00 },93	{ 0x25, 0x00 },94	{ 0x26, 0x00 },95	{ 0x27, 0x2a },96	{ 0x28, 0xc0 },97	{ 0x29, 0xf3 },98	{ 0x2a, 0x33 },99	{ 0x2b, 0x00 },100	{ 0x2c, 0x0c },101	{ 0x31, 0x00 },102	{ 0x36, 0x00 },103	{ 0x37, 0x00 },104	{ 0x38, 0x00 },105	{ 0x39, 0x01 },106	{ 0x3a, 0xee },107	{ 0x3b, 0xff },108	{ 0x3c, 0x7e },109	{ 0x3d, 0xc0 },110	{ 0x3e, 0x26 },111	{ 0x3f, 0x00 },112	{ 0x48, 0x00 },113	{ 0x49, 0x00 },114	{ 0x4a, 0x00 },115	{ 0x4b, 0x04 },116	{ 0x4c, 0x00 },117};118 119static const struct regmap_range sta350_write_regs_range[] = {120	regmap_reg_range(STA350_CONFA,  STA350_AUTO2),121	regmap_reg_range(STA350_C1CFG,  STA350_FDRC2),122	regmap_reg_range(STA350_EQCFG,  STA350_EVOLRES),123	regmap_reg_range(STA350_NSHAPE, STA350_MISC2),124};125 126static const struct regmap_range sta350_read_regs_range[] = {127	regmap_reg_range(STA350_CONFA,  STA350_AUTO2),128	regmap_reg_range(STA350_C1CFG,  STA350_STATUS),129	regmap_reg_range(STA350_EQCFG,  STA350_EVOLRES),130	regmap_reg_range(STA350_NSHAPE, STA350_MISC2),131};132 133static const struct regmap_range sta350_volatile_regs_range[] = {134	regmap_reg_range(STA350_CFADDR2, STA350_CFUD),135	regmap_reg_range(STA350_STATUS,  STA350_STATUS),136};137 138static const struct regmap_access_table sta350_write_regs = {139	.yes_ranges =	sta350_write_regs_range,140	.n_yes_ranges =	ARRAY_SIZE(sta350_write_regs_range),141};142 143static const struct regmap_access_table sta350_read_regs = {144	.yes_ranges =	sta350_read_regs_range,145	.n_yes_ranges =	ARRAY_SIZE(sta350_read_regs_range),146};147 148static const struct regmap_access_table sta350_volatile_regs = {149	.yes_ranges =	sta350_volatile_regs_range,150	.n_yes_ranges =	ARRAY_SIZE(sta350_volatile_regs_range),151};152 153/* regulator power supply names */154static const char * const sta350_supply_names[] = {155	"vdd-dig",	/* digital supply, 3.3V */156	"vdd-pll",	/* pll supply, 3.3V */157	"vcc"		/* power amp supply, 5V - 26V */158};159 160/* codec private data */161struct sta350_priv {162	struct regmap *regmap;163	struct regulator_bulk_data supplies[ARRAY_SIZE(sta350_supply_names)];164	struct sta350_platform_data *pdata;165 166	unsigned int mclk;167	unsigned int format;168 169	u32 coef_shadow[STA350_COEF_COUNT];170	int shutdown;171 172	struct gpio_desc *gpiod_nreset;173	struct gpio_desc *gpiod_power_down;174 175	struct mutex coeff_lock;176};177 178static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12750, 50, 1);179static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);180static const DECLARE_TLV_DB_SCALE(tone_tlv, -1200, 200, 0);181 182static const char * const sta350_drc_ac[] = {183	"Anti-Clipping", "Dynamic Range Compression"184};185static const char * const sta350_auto_gc_mode[] = {186	"User", "AC no clipping", "AC limited clipping (10%)",187	"DRC nighttime listening mode"188};189static const char * const sta350_auto_xo_mode[] = {190	"User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz",191	"200Hz", "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz",192	"340Hz", "360Hz"193};194static const char * const sta350_binary_output[] = {195	"FFX 3-state output - normal operation", "Binary output"196};197static const char * const sta350_limiter_select[] = {198	"Limiter Disabled", "Limiter #1", "Limiter #2"199};200static const char * const sta350_limiter_attack_rate[] = {201	"3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024",202	"0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752",203	"0.0645", "0.0564", "0.0501", "0.0451"204};205static const char * const sta350_limiter_release_rate[] = {206	"0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299",207	"0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137",208	"0.0134", "0.0117", "0.0110", "0.0104"209};210static const char * const sta350_noise_shaper_type[] = {211	"Third order", "Fourth order"212};213 214static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_attack_tlv,215	0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),216	8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),217);218 219static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_release_tlv,220	0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),221	1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),222	2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),223	3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),224	8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),225);226 227static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_attack_tlv,228	0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),229	8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),230	14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),231);232 233static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_release_tlv,234	0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),235	1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),236	3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),237	5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),238	13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),239);240 241static SOC_ENUM_SINGLE_DECL(sta350_drc_ac_enum,242			    STA350_CONFD, STA350_CONFD_DRC_SHIFT,243			    sta350_drc_ac);244static SOC_ENUM_SINGLE_DECL(sta350_noise_shaper_enum,245			    STA350_CONFE, STA350_CONFE_NSBW_SHIFT,246			    sta350_noise_shaper_type);247static SOC_ENUM_SINGLE_DECL(sta350_auto_gc_enum,248			    STA350_AUTO1, STA350_AUTO1_AMGC_SHIFT,249			    sta350_auto_gc_mode);250static SOC_ENUM_SINGLE_DECL(sta350_auto_xo_enum,251			    STA350_AUTO2, STA350_AUTO2_XO_SHIFT,252			    sta350_auto_xo_mode);253static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch1_enum,254			    STA350_C1CFG, STA350_CxCFG_BO_SHIFT,255			    sta350_binary_output);256static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch2_enum,257			    STA350_C2CFG, STA350_CxCFG_BO_SHIFT,258			    sta350_binary_output);259static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch3_enum,260			    STA350_C3CFG, STA350_CxCFG_BO_SHIFT,261			    sta350_binary_output);262static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch1_enum,263			    STA350_C1CFG, STA350_CxCFG_LS_SHIFT,264			    sta350_limiter_select);265static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch2_enum,266			    STA350_C2CFG, STA350_CxCFG_LS_SHIFT,267			    sta350_limiter_select);268static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch3_enum,269			    STA350_C3CFG, STA350_CxCFG_LS_SHIFT,270			    sta350_limiter_select);271static SOC_ENUM_SINGLE_DECL(sta350_limiter1_attack_rate_enum,272			    STA350_L1AR, STA350_LxA_SHIFT,273			    sta350_limiter_attack_rate);274static SOC_ENUM_SINGLE_DECL(sta350_limiter2_attack_rate_enum,275			    STA350_L2AR, STA350_LxA_SHIFT,276			    sta350_limiter_attack_rate);277static SOC_ENUM_SINGLE_DECL(sta350_limiter1_release_rate_enum,278			    STA350_L1AR, STA350_LxR_SHIFT,279			    sta350_limiter_release_rate);280static SOC_ENUM_SINGLE_DECL(sta350_limiter2_release_rate_enum,281			    STA350_L2AR, STA350_LxR_SHIFT,282			    sta350_limiter_release_rate);283 284/*285 * byte array controls for setting biquad, mixer, scaling coefficients;286 * for biquads all five coefficients need to be set in one go,287 * mixer and pre/postscale coefs can be set individually;288 * each coef is 24bit, the bytes are ordered in the same way289 * as given in the STA350 data sheet (big endian; b1, b2, a1, a2, b0)290 */291 292static int sta350_coefficient_info(struct snd_kcontrol *kcontrol,293				   struct snd_ctl_elem_info *uinfo)294{295	int numcoef = kcontrol->private_value >> 16;296	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;297	uinfo->count = 3 * numcoef;298	return 0;299}300 301static int sta350_coefficient_get(struct snd_kcontrol *kcontrol,302				  struct snd_ctl_elem_value *ucontrol)303{304	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);305	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);306	int numcoef = kcontrol->private_value >> 16;307	int index = kcontrol->private_value & 0xffff;308	unsigned int cfud, val;309	int i, ret = 0;310 311	mutex_lock(&sta350->coeff_lock);312 313	/* preserve reserved bits in STA350_CFUD */314	regmap_read(sta350->regmap, STA350_CFUD, &cfud);315	cfud &= 0xf0;316	/*317	 * chip documentation does not say if the bits are self clearing,318	 * so do it explicitly319	 */320	regmap_write(sta350->regmap, STA350_CFUD, cfud);321 322	regmap_write(sta350->regmap, STA350_CFADDR2, index);323	if (numcoef == 1) {324		regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x04);325	} else if (numcoef == 5) {326		regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x08);327	} else {328		ret = -EINVAL;329		goto exit_unlock;330	}331 332	for (i = 0; i < 3 * numcoef; i++) {333		regmap_read(sta350->regmap, STA350_B1CF1 + i, &val);334		ucontrol->value.bytes.data[i] = val;335	}336 337exit_unlock:338	mutex_unlock(&sta350->coeff_lock);339 340	return ret;341}342 343static int sta350_coefficient_put(struct snd_kcontrol *kcontrol,344				  struct snd_ctl_elem_value *ucontrol)345{346	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);347	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);348	int numcoef = kcontrol->private_value >> 16;349	int index = kcontrol->private_value & 0xffff;350	unsigned int cfud;351	int i;352 353	/* preserve reserved bits in STA350_CFUD */354	regmap_read(sta350->regmap, STA350_CFUD, &cfud);355	cfud &= 0xf0;356	/*357	 * chip documentation does not say if the bits are self clearing,358	 * so do it explicitly359	 */360	regmap_write(sta350->regmap, STA350_CFUD, cfud);361 362	regmap_write(sta350->regmap, STA350_CFADDR2, index);363	for (i = 0; i < numcoef && (index + i < STA350_COEF_COUNT); i++)364		sta350->coef_shadow[index + i] =365			  (ucontrol->value.bytes.data[3 * i] << 16)366			| (ucontrol->value.bytes.data[3 * i + 1] << 8)367			| (ucontrol->value.bytes.data[3 * i + 2]);368	for (i = 0; i < 3 * numcoef; i++)369		regmap_write(sta350->regmap, STA350_B1CF1 + i,370			     ucontrol->value.bytes.data[i]);371	if (numcoef == 1)372		regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01);373	else if (numcoef == 5)374		regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x02);375	else376		return -EINVAL;377 378	return 0;379}380 381static int sta350_sync_coef_shadow(struct snd_soc_component *component)382{383	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);384	unsigned int cfud;385	int i;386 387	/* preserve reserved bits in STA350_CFUD */388	regmap_read(sta350->regmap, STA350_CFUD, &cfud);389	cfud &= 0xf0;390 391	for (i = 0; i < STA350_COEF_COUNT; i++) {392		regmap_write(sta350->regmap, STA350_CFADDR2, i);393		regmap_write(sta350->regmap, STA350_B1CF1,394			     (sta350->coef_shadow[i] >> 16) & 0xff);395		regmap_write(sta350->regmap, STA350_B1CF2,396			     (sta350->coef_shadow[i] >> 8) & 0xff);397		regmap_write(sta350->regmap, STA350_B1CF3,398			     (sta350->coef_shadow[i]) & 0xff);399		/*400		 * chip documentation does not say if the bits are401		 * self-clearing, so do it explicitly402		 */403		regmap_write(sta350->regmap, STA350_CFUD, cfud);404		regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01);405	}406	return 0;407}408 409static int sta350_cache_sync(struct snd_soc_component *component)410{411	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);412	unsigned int mute;413	int rc;414 415	/* mute during register sync */416	regmap_read(sta350->regmap, STA350_CFUD, &mute);417	regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE);418	sta350_sync_coef_shadow(component);419	rc = regcache_sync(sta350->regmap);420	regmap_write(sta350->regmap, STA350_MMUTE, mute);421	return rc;422}423 424#define SINGLE_COEF(xname, index) \425{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \426	.info = sta350_coefficient_info, \427	.get = sta350_coefficient_get,\428	.put = sta350_coefficient_put, \429	.private_value = index | (1 << 16) }430 431#define BIQUAD_COEFS(xname, index) \432{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \433	.info = sta350_coefficient_info, \434	.get = sta350_coefficient_get,\435	.put = sta350_coefficient_put, \436	.private_value = index | (5 << 16) }437 438static const struct snd_kcontrol_new sta350_snd_controls[] = {439SOC_SINGLE_TLV("Master Volume", STA350_MVOL, 0, 0xff, 1, mvol_tlv),440/* VOL */441SOC_SINGLE_TLV("Ch1 Volume", STA350_C1VOL, 0, 0xff, 1, chvol_tlv),442SOC_SINGLE_TLV("Ch2 Volume", STA350_C2VOL, 0, 0xff, 1, chvol_tlv),443SOC_SINGLE_TLV("Ch3 Volume", STA350_C3VOL, 0, 0xff, 1, chvol_tlv),444/* CONFD */445SOC_SINGLE("High Pass Filter Bypass Switch",446	   STA350_CONFD, STA350_CONFD_HPB_SHIFT, 1, 1),447SOC_SINGLE("De-emphasis Filter Switch",448	   STA350_CONFD, STA350_CONFD_DEMP_SHIFT, 1, 0),449SOC_SINGLE("DSP Bypass Switch",450	   STA350_CONFD, STA350_CONFD_DSPB_SHIFT, 1, 0),451SOC_SINGLE("Post-scale Link Switch",452	   STA350_CONFD, STA350_CONFD_PSL_SHIFT, 1, 0),453SOC_SINGLE("Biquad Coefficient Link Switch",454	   STA350_CONFD, STA350_CONFD_BQL_SHIFT, 1, 0),455SOC_ENUM("Compressor/Limiter Switch", sta350_drc_ac_enum),456SOC_ENUM("Noise Shaper Bandwidth", sta350_noise_shaper_enum),457SOC_SINGLE("Zero-detect Mute Enable Switch",458	   STA350_CONFD, STA350_CONFD_ZDE_SHIFT, 1, 0),459SOC_SINGLE("Submix Mode Switch",460	   STA350_CONFD, STA350_CONFD_SME_SHIFT, 1, 0),461/* CONFE */462SOC_SINGLE("Zero Cross Switch", STA350_CONFE, STA350_CONFE_ZCE_SHIFT, 1, 0),463SOC_SINGLE("Soft Ramp Switch", STA350_CONFE, STA350_CONFE_SVE_SHIFT, 1, 0),464/* MUTE */465SOC_SINGLE("Master Switch", STA350_MMUTE, STA350_MMUTE_MMUTE_SHIFT, 1, 1),466SOC_SINGLE("Ch1 Switch", STA350_MMUTE, STA350_MMUTE_C1M_SHIFT, 1, 1),467SOC_SINGLE("Ch2 Switch", STA350_MMUTE, STA350_MMUTE_C2M_SHIFT, 1, 1),468SOC_SINGLE("Ch3 Switch", STA350_MMUTE, STA350_MMUTE_C3M_SHIFT, 1, 1),469/* AUTOx */470SOC_ENUM("Automode GC", sta350_auto_gc_enum),471SOC_ENUM("Automode XO", sta350_auto_xo_enum),472/* CxCFG */473SOC_SINGLE("Ch1 Tone Control Bypass Switch",474	   STA350_C1CFG, STA350_CxCFG_TCB_SHIFT, 1, 0),475SOC_SINGLE("Ch2 Tone Control Bypass Switch",476	   STA350_C2CFG, STA350_CxCFG_TCB_SHIFT, 1, 0),477SOC_SINGLE("Ch1 EQ Bypass Switch",478	   STA350_C1CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0),479SOC_SINGLE("Ch2 EQ Bypass Switch",480	   STA350_C2CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0),481SOC_SINGLE("Ch1 Master Volume Bypass Switch",482	   STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0),483SOC_SINGLE("Ch2 Master Volume Bypass Switch",484	   STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0),485SOC_SINGLE("Ch3 Master Volume Bypass Switch",486	   STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0),487SOC_ENUM("Ch1 Binary Output Select", sta350_binary_output_ch1_enum),488SOC_ENUM("Ch2 Binary Output Select", sta350_binary_output_ch2_enum),489SOC_ENUM("Ch3 Binary Output Select", sta350_binary_output_ch3_enum),490SOC_ENUM("Ch1 Limiter Select", sta350_limiter_ch1_enum),491SOC_ENUM("Ch2 Limiter Select", sta350_limiter_ch2_enum),492SOC_ENUM("Ch3 Limiter Select", sta350_limiter_ch3_enum),493/* TONE */494SOC_SINGLE_RANGE_TLV("Bass Tone Control Volume",495		     STA350_TONE, STA350_TONE_BTC_SHIFT, 1, 13, 0, tone_tlv),496SOC_SINGLE_RANGE_TLV("Treble Tone Control Volume",497		     STA350_TONE, STA350_TONE_TTC_SHIFT, 1, 13, 0, tone_tlv),498SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta350_limiter1_attack_rate_enum),499SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta350_limiter2_attack_rate_enum),500SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta350_limiter1_release_rate_enum),501SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta350_limiter2_release_rate_enum),502 503/*504 * depending on mode, the attack/release thresholds have505 * two different enum definitions; provide both506 */507SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)",508	       STA350_L1ATRT, STA350_LxA_SHIFT,509	       16, 0, sta350_limiter_ac_attack_tlv),510SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)",511	       STA350_L2ATRT, STA350_LxA_SHIFT,512	       16, 0, sta350_limiter_ac_attack_tlv),513SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)",514	       STA350_L1ATRT, STA350_LxR_SHIFT,515	       16, 0, sta350_limiter_ac_release_tlv),516SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)",517	       STA350_L2ATRT, STA350_LxR_SHIFT,518	       16, 0, sta350_limiter_ac_release_tlv),519SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)",520	       STA350_L1ATRT, STA350_LxA_SHIFT,521	       16, 0, sta350_limiter_drc_attack_tlv),522SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)",523	       STA350_L2ATRT, STA350_LxA_SHIFT,524	       16, 0, sta350_limiter_drc_attack_tlv),525SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)",526	       STA350_L1ATRT, STA350_LxR_SHIFT,527	       16, 0, sta350_limiter_drc_release_tlv),528SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)",529	       STA350_L2ATRT, STA350_LxR_SHIFT,530	       16, 0, sta350_limiter_drc_release_tlv),531 532BIQUAD_COEFS("Ch1 - Biquad 1", 0),533BIQUAD_COEFS("Ch1 - Biquad 2", 5),534BIQUAD_COEFS("Ch1 - Biquad 3", 10),535BIQUAD_COEFS("Ch1 - Biquad 4", 15),536BIQUAD_COEFS("Ch2 - Biquad 1", 20),537BIQUAD_COEFS("Ch2 - Biquad 2", 25),538BIQUAD_COEFS("Ch2 - Biquad 3", 30),539BIQUAD_COEFS("Ch2 - Biquad 4", 35),540BIQUAD_COEFS("High-pass", 40),541BIQUAD_COEFS("Low-pass", 45),542SINGLE_COEF("Ch1 - Prescale", 50),543SINGLE_COEF("Ch2 - Prescale", 51),544SINGLE_COEF("Ch1 - Postscale", 52),545SINGLE_COEF("Ch2 - Postscale", 53),546SINGLE_COEF("Ch3 - Postscale", 54),547SINGLE_COEF("Thermal warning - Postscale", 55),548SINGLE_COEF("Ch1 - Mix 1", 56),549SINGLE_COEF("Ch1 - Mix 2", 57),550SINGLE_COEF("Ch2 - Mix 1", 58),551SINGLE_COEF("Ch2 - Mix 2", 59),552SINGLE_COEF("Ch3 - Mix 1", 60),553SINGLE_COEF("Ch3 - Mix 2", 61),554};555 556static const struct snd_soc_dapm_widget sta350_dapm_widgets[] = {557SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),558SND_SOC_DAPM_OUTPUT("LEFT"),559SND_SOC_DAPM_OUTPUT("RIGHT"),560SND_SOC_DAPM_OUTPUT("SUB"),561};562 563static const struct snd_soc_dapm_route sta350_dapm_routes[] = {564	{ "LEFT", NULL, "DAC" },565	{ "RIGHT", NULL, "DAC" },566	{ "SUB", NULL, "DAC" },567	{ "DAC", NULL, "Playback" },568};569 570/* MCLK interpolation ratio per fs */571static struct {572	int fs;573	int ir;574} interpolation_ratios[] = {575	{ 32000, 0 },576	{ 44100, 0 },577	{ 48000, 0 },578	{ 88200, 1 },579	{ 96000, 1 },580	{ 176400, 2 },581	{ 192000, 2 },582};583 584/* MCLK to fs clock ratios */585static int mcs_ratio_table[3][6] = {586	{ 768, 512, 384, 256, 128, 576 },587	{ 384, 256, 192, 128,  64,   0 },588	{ 192, 128,  96,  64,  32,   0 },589};590 591/**592 * sta350_set_dai_sysclk - configure MCLK593 * @codec_dai: the codec DAI594 * @clk_id: the clock ID (ignored)595 * @freq: the MCLK input frequency596 * @dir: the clock direction (ignored)597 *598 * The value of MCLK is used to determine which sample rates are supported599 * by the STA350, based on the mcs_ratio_table.600 *601 * This function must be called by the machine driver's 'startup' function,602 * otherwise the list of supported sample rates will not be available in603 * time for ALSA.604 */605static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai,606				 int clk_id, unsigned int freq, int dir)607{608	struct snd_soc_component *component = codec_dai->component;609	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);610 611	dev_dbg(component->dev, "mclk=%u\n", freq);612	sta350->mclk = freq;613 614	return 0;615}616 617/**618 * sta350_set_dai_fmt - configure the codec for the selected audio format619 * @codec_dai: the codec DAI620 * @fmt: a SND_SOC_DAIFMT_x value indicating the data format621 *622 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the623 * codec accordingly.624 */625static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai,626			      unsigned int fmt)627{628	struct snd_soc_component *component = codec_dai->component;629	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);630	unsigned int confb = 0;631 632	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {633	case SND_SOC_DAIFMT_CBC_CFC:634		break;635	default:636		return -EINVAL;637	}638 639	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {640	case SND_SOC_DAIFMT_I2S:641	case SND_SOC_DAIFMT_RIGHT_J:642	case SND_SOC_DAIFMT_LEFT_J:643		sta350->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;644		break;645	default:646		return -EINVAL;647	}648 649	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {650	case SND_SOC_DAIFMT_NB_NF:651		confb |= STA350_CONFB_C2IM;652		break;653	case SND_SOC_DAIFMT_NB_IF:654		confb |= STA350_CONFB_C1IM;655		break;656	default:657		return -EINVAL;658	}659 660	return regmap_update_bits(sta350->regmap, STA350_CONFB,661				  STA350_CONFB_C1IM | STA350_CONFB_C2IM, confb);662}663 664/**665 * sta350_hw_params - program the STA350 with the given hardware parameters.666 * @substream: the audio stream667 * @params: the hardware parameters to set668 * @dai: the SOC DAI (ignored)669 *670 * This function programs the hardware with the values provided.671 * Specifically, the sample rate and the data format.672 */673static int sta350_hw_params(struct snd_pcm_substream *substream,674			    struct snd_pcm_hw_params *params,675			    struct snd_soc_dai *dai)676{677	struct snd_soc_component *component = dai->component;678	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);679	int i, mcs = -EINVAL, ir = -EINVAL;680	unsigned int confa, confb;681	unsigned int rate, ratio;682	int ret;683 684	if (!sta350->mclk) {685		dev_err(component->dev,686			"sta350->mclk is unset. Unable to determine ratio\n");687		return -EIO;688	}689 690	rate = params_rate(params);691	ratio = sta350->mclk / rate;692	dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio);693 694	for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {695		if (interpolation_ratios[i].fs == rate) {696			ir = interpolation_ratios[i].ir;697			break;698		}699	}700 701	if (ir < 0) {702		dev_err(component->dev, "Unsupported samplerate: %u\n", rate);703		return -EINVAL;704	}705 706	for (i = 0; i < 6; i++) {707		if (mcs_ratio_table[ir][i] == ratio) {708			mcs = i;709			break;710		}711	}712 713	if (mcs < 0) {714		dev_err(component->dev, "Unresolvable ratio: %u\n", ratio);715		return -EINVAL;716	}717 718	confa = (ir << STA350_CONFA_IR_SHIFT) |719		(mcs << STA350_CONFA_MCS_SHIFT);720	confb = 0;721 722	switch (params_width(params)) {723	case 24:724		dev_dbg(component->dev, "24bit\n");725		fallthrough;726	case 32:727		dev_dbg(component->dev, "24bit or 32bit\n");728		switch (sta350->format) {729		case SND_SOC_DAIFMT_I2S:730			confb |= 0x0;731			break;732		case SND_SOC_DAIFMT_LEFT_J:733			confb |= 0x1;734			break;735		case SND_SOC_DAIFMT_RIGHT_J:736			confb |= 0x2;737			break;738		}739 740		break;741	case 20:742		dev_dbg(component->dev, "20bit\n");743		switch (sta350->format) {744		case SND_SOC_DAIFMT_I2S:745			confb |= 0x4;746			break;747		case SND_SOC_DAIFMT_LEFT_J:748			confb |= 0x5;749			break;750		case SND_SOC_DAIFMT_RIGHT_J:751			confb |= 0x6;752			break;753		}754 755		break;756	case 18:757		dev_dbg(component->dev, "18bit\n");758		switch (sta350->format) {759		case SND_SOC_DAIFMT_I2S:760			confb |= 0x8;761			break;762		case SND_SOC_DAIFMT_LEFT_J:763			confb |= 0x9;764			break;765		case SND_SOC_DAIFMT_RIGHT_J:766			confb |= 0xa;767			break;768		}769 770		break;771	case 16:772		dev_dbg(component->dev, "16bit\n");773		switch (sta350->format) {774		case SND_SOC_DAIFMT_I2S:775			confb |= 0x0;776			break;777		case SND_SOC_DAIFMT_LEFT_J:778			confb |= 0xd;779			break;780		case SND_SOC_DAIFMT_RIGHT_J:781			confb |= 0xe;782			break;783		}784 785		break;786	default:787		return -EINVAL;788	}789 790	ret = regmap_update_bits(sta350->regmap, STA350_CONFA,791				 STA350_CONFA_MCS_MASK | STA350_CONFA_IR_MASK,792				 confa);793	if (ret < 0)794		return ret;795 796	ret = regmap_update_bits(sta350->regmap, STA350_CONFB,797				 STA350_CONFB_SAI_MASK | STA350_CONFB_SAIFB,798				 confb);799	if (ret < 0)800		return ret;801 802	return 0;803}804 805static int sta350_startup_sequence(struct sta350_priv *sta350)806{807	if (sta350->gpiod_power_down)808		gpiod_set_value(sta350->gpiod_power_down, 1);809 810	if (sta350->gpiod_nreset) {811		gpiod_set_value(sta350->gpiod_nreset, 0);812		mdelay(1);813		gpiod_set_value(sta350->gpiod_nreset, 1);814		mdelay(1);815	}816 817	return 0;818}819 820/**821 * sta350_set_bias_level - DAPM callback822 * @component: the component device823 * @level: DAPM power level824 *825 * This is called by ALSA to put the component into low power mode826 * or to wake it up.  If the component is powered off completely827 * all registers must be restored after power on.828 */829static int sta350_set_bias_level(struct snd_soc_component *component,830				 enum snd_soc_bias_level level)831{832	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);833	int ret;834 835	dev_dbg(component->dev, "level = %d\n", level);836	switch (level) {837	case SND_SOC_BIAS_ON:838		break;839 840	case SND_SOC_BIAS_PREPARE:841		/* Full power on */842		regmap_update_bits(sta350->regmap, STA350_CONFF,843				   STA350_CONFF_PWDN | STA350_CONFF_EAPD,844				   STA350_CONFF_PWDN | STA350_CONFF_EAPD);845		break;846 847	case SND_SOC_BIAS_STANDBY:848		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {849			ret = regulator_bulk_enable(850				ARRAY_SIZE(sta350->supplies),851				sta350->supplies);852			if (ret < 0) {853				dev_err(component->dev,854					"Failed to enable supplies: %d\n",855					ret);856				return ret;857			}858			sta350_startup_sequence(sta350);859			sta350_cache_sync(component);860		}861 862		/* Power down */863		regmap_update_bits(sta350->regmap, STA350_CONFF,864				   STA350_CONFF_PWDN | STA350_CONFF_EAPD,865				   0);866 867		break;868 869	case SND_SOC_BIAS_OFF:870		/* The chip runs through the power down sequence for us */871		regmap_update_bits(sta350->regmap, STA350_CONFF,872				   STA350_CONFF_PWDN | STA350_CONFF_EAPD, 0);873 874		/* power down: low */875		if (sta350->gpiod_power_down)876			gpiod_set_value(sta350->gpiod_power_down, 0);877 878		if (sta350->gpiod_nreset)879			gpiod_set_value(sta350->gpiod_nreset, 0);880 881		regulator_bulk_disable(ARRAY_SIZE(sta350->supplies),882				       sta350->supplies);883		break;884	}885	return 0;886}887 888static const struct snd_soc_dai_ops sta350_dai_ops = {889	.hw_params	= sta350_hw_params,890	.set_sysclk	= sta350_set_dai_sysclk,891	.set_fmt	= sta350_set_dai_fmt,892};893 894static struct snd_soc_dai_driver sta350_dai = {895	.name = "sta350-hifi",896	.playback = {897		.stream_name = "Playback",898		.channels_min = 2,899		.channels_max = 2,900		.rates = STA350_RATES,901		.formats = STA350_FORMATS,902	},903	.ops = &sta350_dai_ops,904};905 906static int sta350_probe(struct snd_soc_component *component)907{908	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);909	struct sta350_platform_data *pdata = sta350->pdata;910	int i, ret = 0, thermal = 0;911 912	ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies),913				    sta350->supplies);914	if (ret < 0) {915		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);916		return ret;917	}918 919	ret = sta350_startup_sequence(sta350);920	if (ret < 0) {921		dev_err(component->dev, "Failed to startup device\n");922		return ret;923	}924 925	/* CONFA */926	if (!pdata->thermal_warning_recovery)927		thermal |= STA350_CONFA_TWAB;928	if (!pdata->thermal_warning_adjustment)929		thermal |= STA350_CONFA_TWRB;930	if (!pdata->fault_detect_recovery)931		thermal |= STA350_CONFA_FDRB;932	regmap_update_bits(sta350->regmap, STA350_CONFA,933			   STA350_CONFA_TWAB | STA350_CONFA_TWRB |934			   STA350_CONFA_FDRB,935			   thermal);936 937	/* CONFC */938	regmap_update_bits(sta350->regmap, STA350_CONFC,939			   STA350_CONFC_OM_MASK,940			   pdata->ffx_power_output_mode941				<< STA350_CONFC_OM_SHIFT);942	regmap_update_bits(sta350->regmap, STA350_CONFC,943			   STA350_CONFC_CSZ_MASK,944			   pdata->drop_compensation_ns945				<< STA350_CONFC_CSZ_SHIFT);946	regmap_update_bits(sta350->regmap,947			   STA350_CONFC,948			   STA350_CONFC_OCRB,949			   pdata->oc_warning_adjustment ?950				STA350_CONFC_OCRB : 0);951 952	/* CONFE */953	regmap_update_bits(sta350->regmap, STA350_CONFE,954			   STA350_CONFE_MPCV,955			   pdata->max_power_use_mpcc ?956				STA350_CONFE_MPCV : 0);957	regmap_update_bits(sta350->regmap, STA350_CONFE,958			   STA350_CONFE_MPC,959			   pdata->max_power_correction ?960				STA350_CONFE_MPC : 0);961	regmap_update_bits(sta350->regmap, STA350_CONFE,962			   STA350_CONFE_AME,963			   pdata->am_reduction_mode ?964				STA350_CONFE_AME : 0);965	regmap_update_bits(sta350->regmap, STA350_CONFE,966			   STA350_CONFE_PWMS,967			   pdata->odd_pwm_speed_mode ?968				STA350_CONFE_PWMS : 0);969	regmap_update_bits(sta350->regmap, STA350_CONFE,970			   STA350_CONFE_DCCV,971			   pdata->distortion_compensation ?972				STA350_CONFE_DCCV : 0);973	/*  CONFF */974	regmap_update_bits(sta350->regmap, STA350_CONFF,975			   STA350_CONFF_IDE,976			   pdata->invalid_input_detect_mute ?977				STA350_CONFF_IDE : 0);978	regmap_update_bits(sta350->regmap, STA350_CONFF,979			   STA350_CONFF_OCFG_MASK,980			   pdata->output_conf981				<< STA350_CONFF_OCFG_SHIFT);982 983	/* channel to output mapping */984	regmap_update_bits(sta350->regmap, STA350_C1CFG,985			   STA350_CxCFG_OM_MASK,986			   pdata->ch1_output_mapping987				<< STA350_CxCFG_OM_SHIFT);988	regmap_update_bits(sta350->regmap, STA350_C2CFG,989			   STA350_CxCFG_OM_MASK,990			   pdata->ch2_output_mapping991				<< STA350_CxCFG_OM_SHIFT);992	regmap_update_bits(sta350->regmap, STA350_C3CFG,993			   STA350_CxCFG_OM_MASK,994			   pdata->ch3_output_mapping995				<< STA350_CxCFG_OM_SHIFT);996 997	/* miscellaneous registers */998	regmap_update_bits(sta350->regmap, STA350_MISC1,999			   STA350_MISC1_CPWMEN,1000			   pdata->activate_mute_output ?1001				STA350_MISC1_CPWMEN : 0);1002	regmap_update_bits(sta350->regmap, STA350_MISC1,1003			   STA350_MISC1_BRIDGOFF,1004			   pdata->bridge_immediate_off ?1005				STA350_MISC1_BRIDGOFF : 0);1006	regmap_update_bits(sta350->regmap, STA350_MISC1,1007			   STA350_MISC1_NSHHPEN,1008			   pdata->noise_shape_dc_cut ?1009				STA350_MISC1_NSHHPEN : 0);1010	regmap_update_bits(sta350->regmap, STA350_MISC1,1011			   STA350_MISC1_RPDNEN,1012			   pdata->powerdown_master_vol ?1013				STA350_MISC1_RPDNEN: 0);1014 1015	regmap_update_bits(sta350->regmap, STA350_MISC2,1016			   STA350_MISC2_PNDLSL_MASK,1017			   pdata->powerdown_delay_divider1018				<< STA350_MISC2_PNDLSL_SHIFT);1019 1020	/* initialize coefficient shadow RAM with reset values */1021	for (i = 4; i <= 49; i += 5)1022		sta350->coef_shadow[i] = 0x400000;1023	for (i = 50; i <= 54; i++)1024		sta350->coef_shadow[i] = 0x7fffff;1025	sta350->coef_shadow[55] = 0x5a9df7;1026	sta350->coef_shadow[56] = 0x7fffff;1027	sta350->coef_shadow[59] = 0x7fffff;1028	sta350->coef_shadow[60] = 0x400000;1029	sta350->coef_shadow[61] = 0x400000;1030 1031	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);1032	/* Bias level configuration will have done an extra enable */1033	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);1034 1035	return 0;1036}1037 1038static void sta350_remove(struct snd_soc_component *component)1039{1040	struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);1041 1042	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);1043}1044 1045static const struct snd_soc_component_driver sta350_component = {1046	.probe			= sta350_probe,1047	.remove			= sta350_remove,1048	.set_bias_level		= sta350_set_bias_level,1049	.controls		= sta350_snd_controls,1050	.num_controls		= ARRAY_SIZE(sta350_snd_controls),1051	.dapm_widgets		= sta350_dapm_widgets,1052	.num_dapm_widgets	= ARRAY_SIZE(sta350_dapm_widgets),1053	.dapm_routes		= sta350_dapm_routes,1054	.num_dapm_routes	= ARRAY_SIZE(sta350_dapm_routes),1055	.suspend_bias_off	= 1,1056	.idle_bias_on		= 1,1057	.use_pmdown_time	= 1,1058	.endianness		= 1,1059};1060 1061static const struct regmap_config sta350_regmap = {1062	.reg_bits =		8,1063	.val_bits =		8,1064	.max_register =		STA350_MISC2,1065	.reg_defaults =		sta350_regs,1066	.num_reg_defaults =	ARRAY_SIZE(sta350_regs),1067	.cache_type =		REGCACHE_MAPLE,1068	.wr_table =		&sta350_write_regs,1069	.rd_table =		&sta350_read_regs,1070	.volatile_table =	&sta350_volatile_regs,1071};1072 1073#ifdef CONFIG_OF1074static const struct of_device_id st350_dt_ids[] = {1075	{ .compatible = "st,sta350", },1076	{ }1077};1078MODULE_DEVICE_TABLE(of, st350_dt_ids);1079 1080static const char * const sta350_ffx_modes[] = {1081	[STA350_FFX_PM_DROP_COMP]		= "drop-compensation",1082	[STA350_FFX_PM_TAPERED_COMP]		= "tapered-compensation",1083	[STA350_FFX_PM_FULL_POWER]		= "full-power-mode",1084	[STA350_FFX_PM_VARIABLE_DROP_COMP]	= "variable-drop-compensation",1085};1086 1087static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350)1088{1089	struct device_node *np = dev->of_node;1090	struct sta350_platform_data *pdata;1091	const char *ffx_power_mode;1092	u16 tmp;1093	u8 tmp8;1094 1095	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);1096	if (!pdata)1097		return -ENOMEM;1098 1099	of_property_read_u8(np, "st,output-conf",1100			    &pdata->output_conf);1101	of_property_read_u8(np, "st,ch1-output-mapping",1102			    &pdata->ch1_output_mapping);1103	of_property_read_u8(np, "st,ch2-output-mapping",1104			    &pdata->ch2_output_mapping);1105	of_property_read_u8(np, "st,ch3-output-mapping",1106			    &pdata->ch3_output_mapping);1107 1108	pdata->thermal_warning_recovery =1109		of_property_read_bool(np, "st,thermal-warning-recovery");1110	pdata->thermal_warning_adjustment =1111		of_property_read_bool(np, "st,thermal-warning-adjustment");1112	pdata->fault_detect_recovery =1113		of_property_read_bool(np, "st,fault-detect-recovery");1114 1115	pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP;1116	if (!of_property_read_string(np, "st,ffx-power-output-mode",1117				     &ffx_power_mode)) {1118		int i, mode = -EINVAL;1119 1120		for (i = 0; i < ARRAY_SIZE(sta350_ffx_modes); i++)1121			if (!strcasecmp(ffx_power_mode, sta350_ffx_modes[i]))1122				mode = i;1123 1124		if (mode < 0)1125			dev_warn(dev, "Unsupported ffx output mode: %s\n",1126				 ffx_power_mode);1127		else1128			pdata->ffx_power_output_mode = mode;1129	}1130 1131	tmp = 140;1132	of_property_read_u16(np, "st,drop-compensation-ns", &tmp);1133	pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;1134 1135	pdata->oc_warning_adjustment =1136		of_property_read_bool(np, "st,overcurrent-warning-adjustment");1137 1138	/* CONFE */1139	pdata->max_power_use_mpcc =1140		of_property_read_bool(np, "st,max-power-use-mpcc");1141	pdata->max_power_correction =1142		of_property_read_bool(np, "st,max-power-correction");1143	pdata->am_reduction_mode =1144		of_property_read_bool(np, "st,am-reduction-mode");1145	pdata->odd_pwm_speed_mode =1146		of_property_read_bool(np, "st,odd-pwm-speed-mode");1147	pdata->distortion_compensation =1148		of_property_read_bool(np, "st,distortion-compensation");1149 1150	/* CONFF */1151	pdata->invalid_input_detect_mute =1152		of_property_read_bool(np, "st,invalid-input-detect-mute");1153 1154	/* MISC */1155	pdata->activate_mute_output =1156		of_property_read_bool(np, "st,activate-mute-output");1157	pdata->bridge_immediate_off =1158		of_property_read_bool(np, "st,bridge-immediate-off");1159	pdata->noise_shape_dc_cut =1160		of_property_read_bool(np, "st,noise-shape-dc-cut");1161	pdata->powerdown_master_vol =1162		of_property_read_bool(np, "st,powerdown-master-volume");1163 1164	if (!of_property_read_u8(np, "st,powerdown-delay-divider", &tmp8)) {1165		if (is_power_of_2(tmp8) && tmp8 >= 1 && tmp8 <= 128)1166			pdata->powerdown_delay_divider = ilog2(tmp8);1167		else1168			dev_warn(dev, "Unsupported powerdown delay divider %d\n",1169				 tmp8);1170	}1171 1172	sta350->pdata = pdata;1173 1174	return 0;1175}1176#endif1177 1178static int sta350_i2c_probe(struct i2c_client *i2c)1179{1180	struct device *dev = &i2c->dev;1181	struct sta350_priv *sta350;1182	int ret, i;1183 1184	sta350 = devm_kzalloc(dev, sizeof(struct sta350_priv), GFP_KERNEL);1185	if (!sta350)1186		return -ENOMEM;1187 1188	mutex_init(&sta350->coeff_lock);1189	sta350->pdata = dev_get_platdata(dev);1190 1191#ifdef CONFIG_OF1192	if (dev->of_node) {1193		ret = sta350_probe_dt(dev, sta350);1194		if (ret < 0)1195			return ret;1196	}1197#endif1198 1199	/* GPIOs */1200	sta350->gpiod_nreset = devm_gpiod_get_optional(dev, "reset",1201						       GPIOD_OUT_LOW);1202	if (IS_ERR(sta350->gpiod_nreset))1203		return PTR_ERR(sta350->gpiod_nreset);1204 1205	sta350->gpiod_power_down = devm_gpiod_get_optional(dev, "power-down",1206							   GPIOD_OUT_LOW);1207	if (IS_ERR(sta350->gpiod_power_down))1208		return PTR_ERR(sta350->gpiod_power_down);1209 1210	/* regulators */1211	for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++)1212		sta350->supplies[i].supply = sta350_supply_names[i];1213 1214	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sta350->supplies),1215				      sta350->supplies);1216	if (ret < 0) {1217		dev_err(dev, "Failed to request supplies: %d\n", ret);1218		return ret;1219	}1220 1221	sta350->regmap = devm_regmap_init_i2c(i2c, &sta350_regmap);1222	if (IS_ERR(sta350->regmap)) {1223		ret = PTR_ERR(sta350->regmap);1224		dev_err(dev, "Failed to init regmap: %d\n", ret);1225		return ret;1226	}1227 1228	i2c_set_clientdata(i2c, sta350);1229 1230	ret = devm_snd_soc_register_component(dev, &sta350_component, &sta350_dai, 1);1231	if (ret < 0)1232		dev_err(dev, "Failed to register component (%d)\n", ret);1233 1234	return ret;1235}1236 1237static void sta350_i2c_remove(struct i2c_client *client)1238{}1239 1240static const struct i2c_device_id sta350_i2c_id[] = {1241	{ "sta350" },1242	{ }1243};1244MODULE_DEVICE_TABLE(i2c, sta350_i2c_id);1245 1246static struct i2c_driver sta350_i2c_driver = {1247	.driver = {1248		.name = "sta350",1249		.of_match_table = of_match_ptr(st350_dt_ids),1250	},1251	.probe =    sta350_i2c_probe,1252	.remove =   sta350_i2c_remove,1253	.id_table = sta350_i2c_id,1254};1255 1256module_i2c_driver(sta350_i2c_driver);1257 1258MODULE_DESCRIPTION("ASoC STA350 driver");1259MODULE_AUTHOR("Sven Brandau <info@brandau.biz>");1260MODULE_LICENSE("GPL");1261