brintos

brintos / linux-shallow public Read only

0
0
Text · 34.4 KiB · bd8848e Raw
1178 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system4 *5 * Copyright: 2011 Raumfeld GmbH6 * Author: Johannes Stezenbach <js@sig21.net>7 *8 * based on code from:9 *	Wolfson Microelectronics PLC.10 *	  Mark Brown <broonie@opensource.wolfsonmicro.com>11 *	Freescale Semiconductor, Inc.12 *	  Timur Tabi <timur@freescale.com>13 */14 15#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__16 17#include <linux/module.h>18#include <linux/moduleparam.h>19#include <linux/init.h>20#include <linux/clk.h>21#include <linux/delay.h>22#include <linux/pm.h>23#include <linux/i2c.h>24#include <linux/of.h>25#include <linux/regmap.h>26#include <linux/regulator/consumer.h>27#include <linux/gpio/consumer.h>28#include <linux/slab.h>29#include <linux/workqueue.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/sta32x.h>39#include "sta32x.h"40 41#define STA32X_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 STA32X_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 sta32x_regs[] = {56	{  0x0, 0x63 },57	{  0x1, 0x80 },58	{  0x2, 0xc2 },59	{  0x3, 0x40 },60	{  0x4, 0xc2 },61	{  0x5, 0x5c },62	{  0x6, 0x10 },63	{  0x7, 0xff },64	{  0x8, 0x60 },65	{  0x9, 0x60 },66	{  0xa, 0x60 },67	{  0xb, 0x80 },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, 0x2d },96	{ 0x28, 0xc0 },97	{ 0x2b, 0x00 },98	{ 0x2c, 0x0c },99};100 101static const struct regmap_range sta32x_write_regs_range[] = {102	regmap_reg_range(STA32X_CONFA,  STA32X_FDRC2),103};104 105static const struct regmap_range sta32x_read_regs_range[] = {106	regmap_reg_range(STA32X_CONFA,  STA32X_FDRC2),107};108 109static const struct regmap_range sta32x_volatile_regs_range[] = {110	regmap_reg_range(STA32X_CFADDR2, STA32X_CFUD),111};112 113static const struct regmap_access_table sta32x_write_regs = {114	.yes_ranges =	sta32x_write_regs_range,115	.n_yes_ranges =	ARRAY_SIZE(sta32x_write_regs_range),116};117 118static const struct regmap_access_table sta32x_read_regs = {119	.yes_ranges =	sta32x_read_regs_range,120	.n_yes_ranges =	ARRAY_SIZE(sta32x_read_regs_range),121};122 123static const struct regmap_access_table sta32x_volatile_regs = {124	.yes_ranges =	sta32x_volatile_regs_range,125	.n_yes_ranges =	ARRAY_SIZE(sta32x_volatile_regs_range),126};127 128/* regulator power supply names */129static const char *sta32x_supply_names[] = {130	"Vdda",	/* analog supply, 3.3VV */131	"Vdd3",	/* digital supply, 3.3V */132	"Vcc"	/* power amp spply, 10V - 36V */133};134 135/* codec private data */136struct sta32x_priv {137	struct regmap *regmap;138	struct clk *xti_clk;139	struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];140	struct snd_soc_component *component;141	struct sta32x_platform_data *pdata;142 143	unsigned int mclk;144	unsigned int format;145 146	u32 coef_shadow[STA32X_COEF_COUNT];147	struct delayed_work watchdog_work;148	int shutdown;149	struct gpio_desc *gpiod_nreset;150	struct mutex coeff_lock;151};152 153static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);154static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);155static const DECLARE_TLV_DB_SCALE(tone_tlv, -120, 200, 0);156 157static const char *sta32x_drc_ac[] = {158	"Anti-Clipping", "Dynamic Range Compression" };159static const char *sta32x_auto_eq_mode[] = {160	"User", "Preset", "Loudness" };161static const char *sta32x_auto_gc_mode[] = {162	"User", "AC no clipping", "AC limited clipping (10%)",163	"DRC nighttime listening mode" };164static const char *sta32x_auto_xo_mode[] = {165	"User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", "200Hz",166	"220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", "340Hz", "360Hz" };167static const char *sta32x_preset_eq_mode[] = {168	"Flat", "Rock", "Soft Rock", "Jazz", "Classical", "Dance", "Pop", "Soft",169	"Hard", "Party", "Vocal", "Hip-Hop", "Dialog", "Bass-boost #1",170	"Bass-boost #2", "Bass-boost #3", "Loudness 1", "Loudness 2",171	"Loudness 3", "Loudness 4", "Loudness 5", "Loudness 6", "Loudness 7",172	"Loudness 8", "Loudness 9", "Loudness 10", "Loudness 11", "Loudness 12",173	"Loudness 13", "Loudness 14", "Loudness 15", "Loudness 16" };174static const char *sta32x_limiter_select[] = {175	"Limiter Disabled", "Limiter #1", "Limiter #2" };176static const char *sta32x_limiter_attack_rate[] = {177	"3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024",178	"0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752",179	"0.0645", "0.0564", "0.0501", "0.0451" };180static const char *sta32x_limiter_release_rate[] = {181	"0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299",182	"0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137",183	"0.0134", "0.0117", "0.0110", "0.0104" };184static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_attack_tlv,185	0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),186	8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),187);188 189static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_release_tlv,190	0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),191	1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),192	2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),193	3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),194	8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),195);196 197static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_attack_tlv,198	0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),199	8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),200	14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),201);202 203static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_release_tlv,204	0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),205	1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),206	3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),207	5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),208	13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),209);210 211static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum,212			    STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,213			    sta32x_drc_ac);214static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum,215			    STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,216			    sta32x_auto_eq_mode);217static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum,218			    STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,219			    sta32x_auto_gc_mode);220static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum,221			    STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,222			    sta32x_auto_xo_mode);223static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum,224			    STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,225			    sta32x_preset_eq_mode);226static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum,227			    STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,228			    sta32x_limiter_select);229static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum,230			    STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,231			    sta32x_limiter_select);232static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum,233			    STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,234			    sta32x_limiter_select);235static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum,236			    STA32X_L1AR, STA32X_LxA_SHIFT,237			    sta32x_limiter_attack_rate);238static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum,239			    STA32X_L2AR, STA32X_LxA_SHIFT,240			    sta32x_limiter_attack_rate);241static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum,242			    STA32X_L1AR, STA32X_LxR_SHIFT,243			    sta32x_limiter_release_rate);244static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum,245			    STA32X_L2AR, STA32X_LxR_SHIFT,246			    sta32x_limiter_release_rate);247 248/* byte array controls for setting biquad, mixer, scaling coefficients;249 * for biquads all five coefficients need to be set in one go,250 * mixer and pre/postscale coefs can be set individually;251 * each coef is 24bit, the bytes are ordered in the same way252 * as given in the STA32x data sheet (big endian; b1, b2, a1, a2, b0)253 */254 255static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,256				   struct snd_ctl_elem_info *uinfo)257{258	int numcoef = kcontrol->private_value >> 16;259	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;260	uinfo->count = 3 * numcoef;261	return 0;262}263 264static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,265				  struct snd_ctl_elem_value *ucontrol)266{267	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);268	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);269	int numcoef = kcontrol->private_value >> 16;270	int index = kcontrol->private_value & 0xffff;271	unsigned int cfud, val;272	int i, ret = 0;273 274	mutex_lock(&sta32x->coeff_lock);275 276	/* preserve reserved bits in STA32X_CFUD */277	regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);278	cfud &= 0xf0;279	/*280	 * chip documentation does not say if the bits are self clearing,281	 * so do it explicitly282	 */283	regmap_write(sta32x->regmap, STA32X_CFUD, cfud);284 285	regmap_write(sta32x->regmap, STA32X_CFADDR2, index);286	if (numcoef == 1) {287		regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x04);288	} else if (numcoef == 5) {289		regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x08);290	} else {291		ret = -EINVAL;292		goto exit_unlock;293	}294 295	for (i = 0; i < 3 * numcoef; i++) {296		regmap_read(sta32x->regmap, STA32X_B1CF1 + i, &val);297		ucontrol->value.bytes.data[i] = val;298	}299 300exit_unlock:301	mutex_unlock(&sta32x->coeff_lock);302 303	return ret;304}305 306static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,307				  struct snd_ctl_elem_value *ucontrol)308{309	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);310	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);311	int numcoef = kcontrol->private_value >> 16;312	int index = kcontrol->private_value & 0xffff;313	unsigned int cfud;314	int i;315 316	/* preserve reserved bits in STA32X_CFUD */317	regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);318	cfud &= 0xf0;319	/*320	 * chip documentation does not say if the bits are self clearing,321	 * so do it explicitly322	 */323	regmap_write(sta32x->regmap, STA32X_CFUD, cfud);324 325	regmap_write(sta32x->regmap, STA32X_CFADDR2, index);326	for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)327		sta32x->coef_shadow[index + i] =328			  (ucontrol->value.bytes.data[3 * i] << 16)329			| (ucontrol->value.bytes.data[3 * i + 1] << 8)330			| (ucontrol->value.bytes.data[3 * i + 2]);331	for (i = 0; i < 3 * numcoef; i++)332		regmap_write(sta32x->regmap, STA32X_B1CF1 + i,333			     ucontrol->value.bytes.data[i]);334	if (numcoef == 1)335		regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01);336	else if (numcoef == 5)337		regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x02);338	else339		return -EINVAL;340 341	return 0;342}343 344static int sta32x_sync_coef_shadow(struct snd_soc_component *component)345{346	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);347	unsigned int cfud;348	int i;349 350	/* preserve reserved bits in STA32X_CFUD */351	regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);352	cfud &= 0xf0;353 354	for (i = 0; i < STA32X_COEF_COUNT; i++) {355		regmap_write(sta32x->regmap, STA32X_CFADDR2, i);356		regmap_write(sta32x->regmap, STA32X_B1CF1,357			     (sta32x->coef_shadow[i] >> 16) & 0xff);358		regmap_write(sta32x->regmap, STA32X_B1CF2,359			     (sta32x->coef_shadow[i] >> 8) & 0xff);360		regmap_write(sta32x->regmap, STA32X_B1CF3,361			     (sta32x->coef_shadow[i]) & 0xff);362		/*363		 * chip documentation does not say if the bits are364		 * self-clearing, so do it explicitly365		 */366		regmap_write(sta32x->regmap, STA32X_CFUD, cfud);367		regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01);368	}369	return 0;370}371 372static int sta32x_cache_sync(struct snd_soc_component *component)373{374	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);375	unsigned int mute;376	int rc;377 378	/* mute during register sync */379	regmap_read(sta32x->regmap, STA32X_MMUTE, &mute);380	regmap_write(sta32x->regmap, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);381	sta32x_sync_coef_shadow(component);382	rc = regcache_sync(sta32x->regmap);383	regmap_write(sta32x->regmap, STA32X_MMUTE, mute);384	return rc;385}386 387/* work around ESD issue where sta32x resets and loses all configuration */388static void sta32x_watchdog(struct work_struct *work)389{390	struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv,391						  watchdog_work.work);392	struct snd_soc_component *component = sta32x->component;393	unsigned int confa, confa_cached;394 395	/* check if sta32x has reset itself */396	confa_cached = snd_soc_component_read(component, STA32X_CONFA);397	regcache_cache_bypass(sta32x->regmap, true);398	confa = snd_soc_component_read(component, STA32X_CONFA);399	regcache_cache_bypass(sta32x->regmap, false);400	if (confa != confa_cached) {401		regcache_mark_dirty(sta32x->regmap);402		sta32x_cache_sync(component);403	}404 405	if (!sta32x->shutdown)406		queue_delayed_work(system_power_efficient_wq,407				   &sta32x->watchdog_work,408				   round_jiffies_relative(HZ));409}410 411static void sta32x_watchdog_start(struct sta32x_priv *sta32x)412{413	if (sta32x->pdata->needs_esd_watchdog) {414		sta32x->shutdown = 0;415		queue_delayed_work(system_power_efficient_wq,416				   &sta32x->watchdog_work,417				   round_jiffies_relative(HZ));418	}419}420 421static void sta32x_watchdog_stop(struct sta32x_priv *sta32x)422{423	if (sta32x->pdata->needs_esd_watchdog) {424		sta32x->shutdown = 1;425		cancel_delayed_work_sync(&sta32x->watchdog_work);426	}427}428 429#define SINGLE_COEF(xname, index) \430{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \431	.info = sta32x_coefficient_info, \432	.get = sta32x_coefficient_get,\433	.put = sta32x_coefficient_put, \434	.private_value = index | (1 << 16) }435 436#define BIQUAD_COEFS(xname, index) \437{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \438	.info = sta32x_coefficient_info, \439	.get = sta32x_coefficient_get,\440	.put = sta32x_coefficient_put, \441	.private_value = index | (5 << 16) }442 443static const struct snd_kcontrol_new sta32x_snd_controls[] = {444SOC_SINGLE_TLV("Master Volume", STA32X_MVOL, 0, 0xff, 1, mvol_tlv),445SOC_SINGLE("Master Switch", STA32X_MMUTE, 0, 1, 1),446SOC_SINGLE("Ch1 Switch", STA32X_MMUTE, 1, 1, 1),447SOC_SINGLE("Ch2 Switch", STA32X_MMUTE, 2, 1, 1),448SOC_SINGLE("Ch3 Switch", STA32X_MMUTE, 3, 1, 1),449SOC_SINGLE_TLV("Ch1 Volume", STA32X_C1VOL, 0, 0xff, 1, chvol_tlv),450SOC_SINGLE_TLV("Ch2 Volume", STA32X_C2VOL, 0, 0xff, 1, chvol_tlv),451SOC_SINGLE_TLV("Ch3 Volume", STA32X_C3VOL, 0, 0xff, 1, chvol_tlv),452SOC_SINGLE("De-emphasis Filter Switch", STA32X_CONFD, STA32X_CONFD_DEMP_SHIFT, 1, 0),453SOC_ENUM("Compressor/Limiter Switch", sta32x_drc_ac_enum),454SOC_SINGLE("Miami Mode Switch", STA32X_CONFD, STA32X_CONFD_MME_SHIFT, 1, 0),455SOC_SINGLE("Zero Cross Switch", STA32X_CONFE, STA32X_CONFE_ZCE_SHIFT, 1, 0),456SOC_SINGLE("Soft Ramp Switch", STA32X_CONFE, STA32X_CONFE_SVE_SHIFT, 1, 0),457SOC_SINGLE("Auto-Mute Switch", STA32X_CONFF, STA32X_CONFF_IDE_SHIFT, 1, 0),458SOC_ENUM("Automode EQ", sta32x_auto_eq_enum),459SOC_ENUM("Automode GC", sta32x_auto_gc_enum),460SOC_ENUM("Automode XO", sta32x_auto_xo_enum),461SOC_ENUM("Preset EQ", sta32x_preset_eq_enum),462SOC_SINGLE("Ch1 Tone Control Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),463SOC_SINGLE("Ch2 Tone Control Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),464SOC_SINGLE("Ch1 EQ Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),465SOC_SINGLE("Ch2 EQ Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),466SOC_SINGLE("Ch1 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),467SOC_SINGLE("Ch2 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),468SOC_SINGLE("Ch3 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),469SOC_ENUM("Ch1 Limiter Select", sta32x_limiter_ch1_enum),470SOC_ENUM("Ch2 Limiter Select", sta32x_limiter_ch2_enum),471SOC_ENUM("Ch3 Limiter Select", sta32x_limiter_ch3_enum),472SOC_SINGLE_TLV("Bass Tone Control", STA32X_TONE, STA32X_TONE_BTC_SHIFT, 15, 0, tone_tlv),473SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, tone_tlv),474SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum),475SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum),476SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),477SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter2_release_rate_enum),478 479/* depending on mode, the attack/release thresholds have480 * two different enum definitions; provide both481 */482SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,483	       16, 0, sta32x_limiter_ac_attack_tlv),484SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,485	       16, 0, sta32x_limiter_ac_attack_tlv),486SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,487	       16, 0, sta32x_limiter_ac_release_tlv),488SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,489	       16, 0, sta32x_limiter_ac_release_tlv),490SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,491	       16, 0, sta32x_limiter_drc_attack_tlv),492SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,493	       16, 0, sta32x_limiter_drc_attack_tlv),494SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,495	       16, 0, sta32x_limiter_drc_release_tlv),496SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,497	       16, 0, sta32x_limiter_drc_release_tlv),498 499BIQUAD_COEFS("Ch1 - Biquad 1", 0),500BIQUAD_COEFS("Ch1 - Biquad 2", 5),501BIQUAD_COEFS("Ch1 - Biquad 3", 10),502BIQUAD_COEFS("Ch1 - Biquad 4", 15),503BIQUAD_COEFS("Ch2 - Biquad 1", 20),504BIQUAD_COEFS("Ch2 - Biquad 2", 25),505BIQUAD_COEFS("Ch2 - Biquad 3", 30),506BIQUAD_COEFS("Ch2 - Biquad 4", 35),507BIQUAD_COEFS("High-pass", 40),508BIQUAD_COEFS("Low-pass", 45),509SINGLE_COEF("Ch1 - Prescale", 50),510SINGLE_COEF("Ch2 - Prescale", 51),511SINGLE_COEF("Ch1 - Postscale", 52),512SINGLE_COEF("Ch2 - Postscale", 53),513SINGLE_COEF("Ch3 - Postscale", 54),514SINGLE_COEF("Thermal warning - Postscale", 55),515SINGLE_COEF("Ch1 - Mix 1", 56),516SINGLE_COEF("Ch1 - Mix 2", 57),517SINGLE_COEF("Ch2 - Mix 1", 58),518SINGLE_COEF("Ch2 - Mix 2", 59),519SINGLE_COEF("Ch3 - Mix 1", 60),520SINGLE_COEF("Ch3 - Mix 2", 61),521};522 523static const struct snd_soc_dapm_widget sta32x_dapm_widgets[] = {524SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),525SND_SOC_DAPM_OUTPUT("LEFT"),526SND_SOC_DAPM_OUTPUT("RIGHT"),527SND_SOC_DAPM_OUTPUT("SUB"),528};529 530static const struct snd_soc_dapm_route sta32x_dapm_routes[] = {531	{ "LEFT", NULL, "DAC" },532	{ "RIGHT", NULL, "DAC" },533	{ "SUB", NULL, "DAC" },534};535 536/* MCLK interpolation ratio per fs */537static struct {538	int fs;539	int ir;540} interpolation_ratios[] = {541	{ 32000, 0 },542	{ 44100, 0 },543	{ 48000, 0 },544	{ 88200, 1 },545	{ 96000, 1 },546	{ 176400, 2 },547	{ 192000, 2 },548};549 550/* MCLK to fs clock ratios */551static int mcs_ratio_table[3][7] = {552	{ 768, 512, 384, 256, 128, 576, 0 },553	{ 384, 256, 192, 128,  64,   0 },554	{ 384, 256, 192, 128,  64,   0 },555};556 557/**558 * sta32x_set_dai_sysclk - configure MCLK559 * @codec_dai: the codec DAI560 * @clk_id: the clock ID (ignored)561 * @freq: the MCLK input frequency562 * @dir: the clock direction (ignored)563 *564 * The value of MCLK is used to determine which sample rates are supported565 * by the STA32X, based on the mclk_ratios table.566 *567 * This function must be called by the machine driver's 'startup' function,568 * otherwise the list of supported sample rates will not be available in569 * time for ALSA.570 *571 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause572 * theoretically possible sample rates to be enabled. Call it again with a573 * proper value set one the external clock is set (most probably you would do574 * that from a machine's driver 'hw_param' hook.575 */576static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,577		int clk_id, unsigned int freq, int dir)578{579	struct snd_soc_component *component = codec_dai->component;580	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);581 582	dev_dbg(component->dev, "mclk=%u\n", freq);583	sta32x->mclk = freq;584 585	return 0;586}587 588/**589 * sta32x_set_dai_fmt - configure the codec for the selected audio format590 * @codec_dai: the codec DAI591 * @fmt: a SND_SOC_DAIFMT_x value indicating the data format592 *593 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the594 * codec accordingly.595 */596static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,597			      unsigned int fmt)598{599	struct snd_soc_component *component = codec_dai->component;600	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);601	u8 confb = 0;602 603	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {604	case SND_SOC_DAIFMT_CBC_CFC:605		break;606	default:607		return -EINVAL;608	}609 610	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {611	case SND_SOC_DAIFMT_I2S:612	case SND_SOC_DAIFMT_RIGHT_J:613	case SND_SOC_DAIFMT_LEFT_J:614		sta32x->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;615		break;616	default:617		return -EINVAL;618	}619 620	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {621	case SND_SOC_DAIFMT_NB_NF:622		confb |= STA32X_CONFB_C2IM;623		break;624	case SND_SOC_DAIFMT_NB_IF:625		confb |= STA32X_CONFB_C1IM;626		break;627	default:628		return -EINVAL;629	}630 631	return regmap_update_bits(sta32x->regmap, STA32X_CONFB,632				  STA32X_CONFB_C1IM | STA32X_CONFB_C2IM, confb);633}634 635/**636 * sta32x_hw_params - program the STA32X with the given hardware parameters.637 * @substream: the audio stream638 * @params: the hardware parameters to set639 * @dai: the SOC DAI (ignored)640 *641 * This function programs the hardware with the values provided.642 * Specifically, the sample rate and the data format.643 */644static int sta32x_hw_params(struct snd_pcm_substream *substream,645			    struct snd_pcm_hw_params *params,646			    struct snd_soc_dai *dai)647{648	struct snd_soc_component *component = dai->component;649	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);650	int i, mcs = -EINVAL, ir = -EINVAL;651	unsigned int confa, confb;652	unsigned int rate, ratio;653	int ret;654 655	if (!sta32x->mclk) {656		dev_err(component->dev,657			"sta32x->mclk is unset. Unable to determine ratio\n");658		return -EIO;659	}660 661	rate = params_rate(params);662	ratio = sta32x->mclk / rate;663	dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio);664 665	for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {666		if (interpolation_ratios[i].fs == rate) {667			ir = interpolation_ratios[i].ir;668			break;669		}670	}671 672	if (ir < 0) {673		dev_err(component->dev, "Unsupported samplerate: %u\n", rate);674		return -EINVAL;675	}676 677	for (i = 0; i < 6; i++) {678		if (mcs_ratio_table[ir][i] == ratio) {679			mcs = i;680			break;681		}682	}683 684	if (mcs < 0) {685		dev_err(component->dev, "Unresolvable ratio: %u\n", ratio);686		return -EINVAL;687	}688 689	confa = (ir << STA32X_CONFA_IR_SHIFT) |690		(mcs << STA32X_CONFA_MCS_SHIFT);691	confb = 0;692 693	switch (params_width(params)) {694	case 24:695		dev_dbg(component->dev, "24bit\n");696		fallthrough;697	case 32:698		dev_dbg(component->dev, "24bit or 32bit\n");699		switch (sta32x->format) {700		case SND_SOC_DAIFMT_I2S:701			confb |= 0x0;702			break;703		case SND_SOC_DAIFMT_LEFT_J:704			confb |= 0x1;705			break;706		case SND_SOC_DAIFMT_RIGHT_J:707			confb |= 0x2;708			break;709		}710 711		break;712	case 20:713		dev_dbg(component->dev, "20bit\n");714		switch (sta32x->format) {715		case SND_SOC_DAIFMT_I2S:716			confb |= 0x4;717			break;718		case SND_SOC_DAIFMT_LEFT_J:719			confb |= 0x5;720			break;721		case SND_SOC_DAIFMT_RIGHT_J:722			confb |= 0x6;723			break;724		}725 726		break;727	case 18:728		dev_dbg(component->dev, "18bit\n");729		switch (sta32x->format) {730		case SND_SOC_DAIFMT_I2S:731			confb |= 0x8;732			break;733		case SND_SOC_DAIFMT_LEFT_J:734			confb |= 0x9;735			break;736		case SND_SOC_DAIFMT_RIGHT_J:737			confb |= 0xa;738			break;739		}740 741		break;742	case 16:743		dev_dbg(component->dev, "16bit\n");744		switch (sta32x->format) {745		case SND_SOC_DAIFMT_I2S:746			confb |= 0x0;747			break;748		case SND_SOC_DAIFMT_LEFT_J:749			confb |= 0xd;750			break;751		case SND_SOC_DAIFMT_RIGHT_J:752			confb |= 0xe;753			break;754		}755 756		break;757	default:758		return -EINVAL;759	}760 761	ret = regmap_update_bits(sta32x->regmap, STA32X_CONFA,762				 STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK,763				 confa);764	if (ret < 0)765		return ret;766 767	ret = regmap_update_bits(sta32x->regmap, STA32X_CONFB,768				 STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB,769				 confb);770	if (ret < 0)771		return ret;772 773	return 0;774}775 776static int sta32x_startup_sequence(struct sta32x_priv *sta32x)777{778	if (sta32x->gpiod_nreset) {779		gpiod_set_value(sta32x->gpiod_nreset, 0);780		mdelay(1);781		gpiod_set_value(sta32x->gpiod_nreset, 1);782		mdelay(1);783	}784 785	return 0;786}787 788/**789 * sta32x_set_bias_level - DAPM callback790 * @component: the component device791 * @level: DAPM power level792 *793 * This is called by ALSA to put the component into low power mode794 * or to wake it up.  If the component is powered off completely795 * all registers must be restored after power on.796 */797static int sta32x_set_bias_level(struct snd_soc_component *component,798				 enum snd_soc_bias_level level)799{800	int ret;801	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);802 803	dev_dbg(component->dev, "level = %d\n", level);804	switch (level) {805	case SND_SOC_BIAS_ON:806		break;807 808	case SND_SOC_BIAS_PREPARE:809		/* Full power on */810		regmap_update_bits(sta32x->regmap, STA32X_CONFF,811				    STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,812				    STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);813		break;814 815	case SND_SOC_BIAS_STANDBY:816		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {817			ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),818						    sta32x->supplies);819			if (ret != 0) {820				dev_err(component->dev,821					"Failed to enable supplies: %d\n", ret);822				return ret;823			}824 825			sta32x_startup_sequence(sta32x);826			sta32x_cache_sync(component);827			sta32x_watchdog_start(sta32x);828		}829 830		/* Power down */831		regmap_update_bits(sta32x->regmap, STA32X_CONFF,832				   STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,833				   0);834 835		break;836 837	case SND_SOC_BIAS_OFF:838		/* The chip runs through the power down sequence for us. */839		regmap_update_bits(sta32x->regmap, STA32X_CONFF,840				   STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, 0);841		msleep(300);842		sta32x_watchdog_stop(sta32x);843 844		gpiod_set_value(sta32x->gpiod_nreset, 0);845 846		regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),847				       sta32x->supplies);848		break;849	}850	return 0;851}852 853static const struct snd_soc_dai_ops sta32x_dai_ops = {854	.hw_params	= sta32x_hw_params,855	.set_sysclk	= sta32x_set_dai_sysclk,856	.set_fmt	= sta32x_set_dai_fmt,857};858 859static struct snd_soc_dai_driver sta32x_dai = {860	.name = "sta32x-hifi",861	.playback = {862		.stream_name = "Playback",863		.channels_min = 2,864		.channels_max = 2,865		.rates = STA32X_RATES,866		.formats = STA32X_FORMATS,867	},868	.ops = &sta32x_dai_ops,869};870 871static int sta32x_probe(struct snd_soc_component *component)872{873	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);874	struct sta32x_platform_data *pdata = sta32x->pdata;875	int i, ret = 0, thermal = 0;876 877	sta32x->component = component;878 879	if (sta32x->xti_clk) {880		ret = clk_prepare_enable(sta32x->xti_clk);881		if (ret != 0) {882			dev_err(component->dev,883				"Failed to enable clock: %d\n", ret);884			return ret;885		}886	}887 888	ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),889				    sta32x->supplies);890	if (ret != 0) {891		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);892		goto err_clk_disable_unprepare;893	}894 895	ret = sta32x_startup_sequence(sta32x);896	if (ret < 0) {897		dev_err(component->dev, "Failed to startup device\n");898		goto err_regulator_bulk_disable;899	}900 901	/* CONFA */902	if (!pdata->thermal_warning_recovery)903		thermal |= STA32X_CONFA_TWAB;904	if (!pdata->thermal_warning_adjustment)905		thermal |= STA32X_CONFA_TWRB;906	if (!pdata->fault_detect_recovery)907		thermal |= STA32X_CONFA_FDRB;908	regmap_update_bits(sta32x->regmap, STA32X_CONFA,909			   STA32X_CONFA_TWAB | STA32X_CONFA_TWRB |910			   STA32X_CONFA_FDRB,911			   thermal);912 913	/* CONFC */914	regmap_update_bits(sta32x->regmap, STA32X_CONFC,915			   STA32X_CONFC_CSZ_MASK,916			   pdata->drop_compensation_ns917				<< STA32X_CONFC_CSZ_SHIFT);918 919	/* CONFE */920	regmap_update_bits(sta32x->regmap, STA32X_CONFE,921			   STA32X_CONFE_MPCV,922			   pdata->max_power_use_mpcc ?923				STA32X_CONFE_MPCV : 0);924	regmap_update_bits(sta32x->regmap, STA32X_CONFE,925			   STA32X_CONFE_MPC,926			   pdata->max_power_correction ?927				STA32X_CONFE_MPC : 0);928	regmap_update_bits(sta32x->regmap, STA32X_CONFE,929			   STA32X_CONFE_AME,930			   pdata->am_reduction_mode ?931				STA32X_CONFE_AME : 0);932	regmap_update_bits(sta32x->regmap, STA32X_CONFE,933			   STA32X_CONFE_PWMS,934			   pdata->odd_pwm_speed_mode ?935				STA32X_CONFE_PWMS : 0);936 937	/*  CONFF */938	regmap_update_bits(sta32x->regmap, STA32X_CONFF,939			   STA32X_CONFF_IDE,940			   pdata->invalid_input_detect_mute ?941				STA32X_CONFF_IDE : 0);942 943	/* select output configuration  */944	regmap_update_bits(sta32x->regmap, STA32X_CONFF,945			   STA32X_CONFF_OCFG_MASK,946			   pdata->output_conf947				<< STA32X_CONFF_OCFG_SHIFT);948 949	/* channel to output mapping */950	regmap_update_bits(sta32x->regmap, STA32X_C1CFG,951			   STA32X_CxCFG_OM_MASK,952			   pdata->ch1_output_mapping953				<< STA32X_CxCFG_OM_SHIFT);954	regmap_update_bits(sta32x->regmap, STA32X_C2CFG,955			   STA32X_CxCFG_OM_MASK,956			   pdata->ch2_output_mapping957				<< STA32X_CxCFG_OM_SHIFT);958	regmap_update_bits(sta32x->regmap, STA32X_C3CFG,959			   STA32X_CxCFG_OM_MASK,960			   pdata->ch3_output_mapping961				<< STA32X_CxCFG_OM_SHIFT);962 963	/* initialize coefficient shadow RAM with reset values */964	for (i = 4; i <= 49; i += 5)965		sta32x->coef_shadow[i] = 0x400000;966	for (i = 50; i <= 54; i++)967		sta32x->coef_shadow[i] = 0x7fffff;968	sta32x->coef_shadow[55] = 0x5a9df7;969	sta32x->coef_shadow[56] = 0x7fffff;970	sta32x->coef_shadow[59] = 0x7fffff;971	sta32x->coef_shadow[60] = 0x400000;972	sta32x->coef_shadow[61] = 0x400000;973 974	if (sta32x->pdata->needs_esd_watchdog)975		INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);976 977	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);978	/* Bias level configuration will have done an extra enable */979	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);980 981	return 0;982 983err_regulator_bulk_disable:984	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);985err_clk_disable_unprepare:986	if (sta32x->xti_clk)987		clk_disable_unprepare(sta32x->xti_clk);988	return ret;989}990 991static void sta32x_remove(struct snd_soc_component *component)992{993	struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);994 995	sta32x_watchdog_stop(sta32x);996	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);997 998	if (sta32x->xti_clk)999		clk_disable_unprepare(sta32x->xti_clk);1000}1001 1002static const struct snd_soc_component_driver sta32x_component = {1003	.probe			= sta32x_probe,1004	.remove			= sta32x_remove,1005	.set_bias_level		= sta32x_set_bias_level,1006	.controls		= sta32x_snd_controls,1007	.num_controls		= ARRAY_SIZE(sta32x_snd_controls),1008	.dapm_widgets		= sta32x_dapm_widgets,1009	.num_dapm_widgets	= ARRAY_SIZE(sta32x_dapm_widgets),1010	.dapm_routes		= sta32x_dapm_routes,1011	.num_dapm_routes	= ARRAY_SIZE(sta32x_dapm_routes),1012	.suspend_bias_off	= 1,1013	.idle_bias_on		= 1,1014	.use_pmdown_time	= 1,1015	.endianness		= 1,1016};1017 1018static const struct regmap_config sta32x_regmap = {1019	.reg_bits =		8,1020	.val_bits =		8,1021	.max_register =		STA32X_FDRC2,1022	.reg_defaults =		sta32x_regs,1023	.num_reg_defaults =	ARRAY_SIZE(sta32x_regs),1024	.cache_type =		REGCACHE_MAPLE,1025	.wr_table =		&sta32x_write_regs,1026	.rd_table =		&sta32x_read_regs,1027	.volatile_table =	&sta32x_volatile_regs,1028};1029 1030#ifdef CONFIG_OF1031static const struct of_device_id st32x_dt_ids[] = {1032	{ .compatible = "st,sta32x", },1033	{ }1034};1035MODULE_DEVICE_TABLE(of, st32x_dt_ids);1036 1037static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x)1038{1039	struct device_node *np = dev->of_node;1040	struct sta32x_platform_data *pdata;1041	u16 tmp;1042 1043	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);1044	if (!pdata)1045		return -ENOMEM;1046 1047	of_property_read_u8(np, "st,output-conf",1048			    &pdata->output_conf);1049	of_property_read_u8(np, "st,ch1-output-mapping",1050			    &pdata->ch1_output_mapping);1051	of_property_read_u8(np, "st,ch2-output-mapping",1052			    &pdata->ch2_output_mapping);1053	of_property_read_u8(np, "st,ch3-output-mapping",1054			    &pdata->ch3_output_mapping);1055 1056	pdata->fault_detect_recovery =1057		of_property_read_bool(np, "st,fault-detect-recovery");1058	pdata->thermal_warning_recovery =1059		of_property_read_bool(np, "st,thermal-warning-recovery");1060	pdata->thermal_warning_adjustment =1061		of_property_read_bool(np, "st,thermal-warning-adjustment");1062	pdata->needs_esd_watchdog =1063		of_property_read_bool(np, "st,needs_esd_watchdog");1064 1065	tmp = 140;1066	of_property_read_u16(np, "st,drop-compensation-ns", &tmp);1067	pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;1068 1069	/* CONFE */1070	pdata->max_power_use_mpcc =1071		of_property_read_bool(np, "st,max-power-use-mpcc");1072	pdata->max_power_correction =1073		of_property_read_bool(np, "st,max-power-correction");1074	pdata->am_reduction_mode =1075		of_property_read_bool(np, "st,am-reduction-mode");1076	pdata->odd_pwm_speed_mode =1077		of_property_read_bool(np, "st,odd-pwm-speed-mode");1078 1079	/* CONFF */1080	pdata->invalid_input_detect_mute =1081		of_property_read_bool(np, "st,invalid-input-detect-mute");1082 1083	sta32x->pdata = pdata;1084 1085	return 0;1086}1087#endif1088 1089static int sta32x_i2c_probe(struct i2c_client *i2c)1090{1091	struct device *dev = &i2c->dev;1092	struct sta32x_priv *sta32x;1093	int ret, i;1094 1095	sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv),1096			      GFP_KERNEL);1097	if (!sta32x)1098		return -ENOMEM;1099 1100	mutex_init(&sta32x->coeff_lock);1101	sta32x->pdata = dev_get_platdata(dev);1102 1103#ifdef CONFIG_OF1104	if (dev->of_node) {1105		ret = sta32x_probe_dt(dev, sta32x);1106		if (ret < 0)1107			return ret;1108	}1109#endif1110 1111	/* Clock */1112	sta32x->xti_clk = devm_clk_get(dev, "xti");1113	if (IS_ERR(sta32x->xti_clk)) {1114		ret = PTR_ERR(sta32x->xti_clk);1115 1116		if (ret == -EPROBE_DEFER)1117			return ret;1118 1119		sta32x->xti_clk = NULL;1120	}1121 1122	/* GPIOs */1123	sta32x->gpiod_nreset = devm_gpiod_get_optional(dev, "reset",1124						       GPIOD_OUT_LOW);1125	if (IS_ERR(sta32x->gpiod_nreset))1126		return PTR_ERR(sta32x->gpiod_nreset);1127 1128	/* regulators */1129	for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)1130		sta32x->supplies[i].supply = sta32x_supply_names[i];1131 1132	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(sta32x->supplies),1133				      sta32x->supplies);1134	if (ret != 0) {1135		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);1136		return ret;1137	}1138 1139	sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap);1140	if (IS_ERR(sta32x->regmap)) {1141		ret = PTR_ERR(sta32x->regmap);1142		dev_err(dev, "Failed to init regmap: %d\n", ret);1143		return ret;1144	}1145 1146	i2c_set_clientdata(i2c, sta32x);1147 1148	ret = devm_snd_soc_register_component(dev, &sta32x_component,1149					      &sta32x_dai, 1);1150	if (ret < 0)1151		dev_err(dev, "Failed to register component (%d)\n", ret);1152 1153	return ret;1154}1155 1156static const struct i2c_device_id sta32x_i2c_id[] = {1157	{ "sta326" },1158	{ "sta328" },1159	{ "sta329" },1160	{ }1161};1162MODULE_DEVICE_TABLE(i2c, sta32x_i2c_id);1163 1164static struct i2c_driver sta32x_i2c_driver = {1165	.driver = {1166		.name = "sta32x",1167		.of_match_table = of_match_ptr(st32x_dt_ids),1168	},1169	.probe = sta32x_i2c_probe,1170	.id_table = sta32x_i2c_id,1171};1172 1173module_i2c_driver(sta32x_i2c_driver);1174 1175MODULE_DESCRIPTION("ASoC STA32X driver");1176MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");1177MODULE_LICENSE("GPL");1178