162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// tfa9879.c  --  driver for NXP Semiconductors TFA9879
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (C) 2014 Axentia Technologies AB
662306a36Sopenharmony_ci// Author: Peter Rosin <peda@axentia.se>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <linux/init.h>
1062306a36Sopenharmony_ci#include <linux/i2c.h>
1162306a36Sopenharmony_ci#include <linux/regmap.h>
1262306a36Sopenharmony_ci#include <sound/soc.h>
1362306a36Sopenharmony_ci#include <sound/tlv.h>
1462306a36Sopenharmony_ci#include <sound/pcm_params.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "tfa9879.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistruct tfa9879_priv {
1962306a36Sopenharmony_ci	struct regmap *regmap;
2062306a36Sopenharmony_ci	int lsb_justified;
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic int tfa9879_hw_params(struct snd_pcm_substream *substream,
2462306a36Sopenharmony_ci			     struct snd_pcm_hw_params *params,
2562306a36Sopenharmony_ci			     struct snd_soc_dai *dai)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	struct snd_soc_component *component = dai->component;
2862306a36Sopenharmony_ci	struct tfa9879_priv *tfa9879 = snd_soc_component_get_drvdata(component);
2962306a36Sopenharmony_ci	int fs;
3062306a36Sopenharmony_ci	int i2s_set = 0;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	switch (params_rate(params)) {
3362306a36Sopenharmony_ci	case 8000:
3462306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_8000;
3562306a36Sopenharmony_ci		break;
3662306a36Sopenharmony_ci	case 11025:
3762306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_11025;
3862306a36Sopenharmony_ci		break;
3962306a36Sopenharmony_ci	case 12000:
4062306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_12000;
4162306a36Sopenharmony_ci		break;
4262306a36Sopenharmony_ci	case 16000:
4362306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_16000;
4462306a36Sopenharmony_ci		break;
4562306a36Sopenharmony_ci	case 22050:
4662306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_22050;
4762306a36Sopenharmony_ci		break;
4862306a36Sopenharmony_ci	case 24000:
4962306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_24000;
5062306a36Sopenharmony_ci		break;
5162306a36Sopenharmony_ci	case 32000:
5262306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_32000;
5362306a36Sopenharmony_ci		break;
5462306a36Sopenharmony_ci	case 44100:
5562306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_44100;
5662306a36Sopenharmony_ci		break;
5762306a36Sopenharmony_ci	case 48000:
5862306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_48000;
5962306a36Sopenharmony_ci		break;
6062306a36Sopenharmony_ci	case 64000:
6162306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_64000;
6262306a36Sopenharmony_ci		break;
6362306a36Sopenharmony_ci	case 88200:
6462306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_88200;
6562306a36Sopenharmony_ci		break;
6662306a36Sopenharmony_ci	case 96000:
6762306a36Sopenharmony_ci		fs = TFA9879_I2S_FS_96000;
6862306a36Sopenharmony_ci		break;
6962306a36Sopenharmony_ci	default:
7062306a36Sopenharmony_ci		return -EINVAL;
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	switch (params_width(params)) {
7462306a36Sopenharmony_ci	case 16:
7562306a36Sopenharmony_ci		i2s_set = TFA9879_I2S_SET_LSB_J_16;
7662306a36Sopenharmony_ci		break;
7762306a36Sopenharmony_ci	case 24:
7862306a36Sopenharmony_ci		i2s_set = TFA9879_I2S_SET_LSB_J_24;
7962306a36Sopenharmony_ci		break;
8062306a36Sopenharmony_ci	default:
8162306a36Sopenharmony_ci		return -EINVAL;
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	if (tfa9879->lsb_justified)
8562306a36Sopenharmony_ci		snd_soc_component_update_bits(component,
8662306a36Sopenharmony_ci					      TFA9879_SERIAL_INTERFACE_1,
8762306a36Sopenharmony_ci					      TFA9879_I2S_SET_MASK,
8862306a36Sopenharmony_ci					      i2s_set << TFA9879_I2S_SET_SHIFT);
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
9162306a36Sopenharmony_ci				      TFA9879_I2S_FS_MASK,
9262306a36Sopenharmony_ci				      fs << TFA9879_I2S_FS_SHIFT);
9362306a36Sopenharmony_ci	return 0;
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistatic int tfa9879_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	struct snd_soc_component *component = dai->component;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	snd_soc_component_update_bits(component, TFA9879_MISC_CONTROL,
10162306a36Sopenharmony_ci				      TFA9879_S_MUTE_MASK,
10262306a36Sopenharmony_ci				      !!mute << TFA9879_S_MUTE_SHIFT);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	return 0;
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	struct snd_soc_component *component = dai->component;
11062306a36Sopenharmony_ci	struct tfa9879_priv *tfa9879 = snd_soc_component_get_drvdata(component);
11162306a36Sopenharmony_ci	int i2s_set;
11262306a36Sopenharmony_ci	int sck_pol;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
11562306a36Sopenharmony_ci	case SND_SOC_DAIFMT_CBC_CFC:
11662306a36Sopenharmony_ci		break;
11762306a36Sopenharmony_ci	default:
11862306a36Sopenharmony_ci		return -EINVAL;
11962306a36Sopenharmony_ci	}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
12262306a36Sopenharmony_ci	case SND_SOC_DAIFMT_NB_NF:
12362306a36Sopenharmony_ci		sck_pol = TFA9879_SCK_POL_NORMAL;
12462306a36Sopenharmony_ci		break;
12562306a36Sopenharmony_ci	case SND_SOC_DAIFMT_IB_NF:
12662306a36Sopenharmony_ci		sck_pol = TFA9879_SCK_POL_INVERSE;
12762306a36Sopenharmony_ci		break;
12862306a36Sopenharmony_ci	default:
12962306a36Sopenharmony_ci		return -EINVAL;
13062306a36Sopenharmony_ci	}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
13362306a36Sopenharmony_ci	case SND_SOC_DAIFMT_I2S:
13462306a36Sopenharmony_ci		tfa9879->lsb_justified = 0;
13562306a36Sopenharmony_ci		i2s_set = TFA9879_I2S_SET_I2S_24;
13662306a36Sopenharmony_ci		break;
13762306a36Sopenharmony_ci	case SND_SOC_DAIFMT_LEFT_J:
13862306a36Sopenharmony_ci		tfa9879->lsb_justified = 0;
13962306a36Sopenharmony_ci		i2s_set = TFA9879_I2S_SET_MSB_J_24;
14062306a36Sopenharmony_ci		break;
14162306a36Sopenharmony_ci	case SND_SOC_DAIFMT_RIGHT_J:
14262306a36Sopenharmony_ci		tfa9879->lsb_justified = 1;
14362306a36Sopenharmony_ci		i2s_set = TFA9879_I2S_SET_LSB_J_24;
14462306a36Sopenharmony_ci		break;
14562306a36Sopenharmony_ci	default:
14662306a36Sopenharmony_ci		return -EINVAL;
14762306a36Sopenharmony_ci	}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
15062306a36Sopenharmony_ci				      TFA9879_SCK_POL_MASK,
15162306a36Sopenharmony_ci				      sck_pol << TFA9879_SCK_POL_SHIFT);
15262306a36Sopenharmony_ci	snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
15362306a36Sopenharmony_ci				      TFA9879_I2S_SET_MASK,
15462306a36Sopenharmony_ci				      i2s_set << TFA9879_I2S_SET_SHIFT);
15562306a36Sopenharmony_ci	return 0;
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic const struct reg_default tfa9879_regs[] = {
15962306a36Sopenharmony_ci	{ TFA9879_DEVICE_CONTROL,	0x0000 }, /* 0x00 */
16062306a36Sopenharmony_ci	{ TFA9879_SERIAL_INTERFACE_1,	0x0a18 }, /* 0x01 */
16162306a36Sopenharmony_ci	{ TFA9879_PCM_IOM2_FORMAT_1,	0x0007 }, /* 0x02 */
16262306a36Sopenharmony_ci	{ TFA9879_SERIAL_INTERFACE_2,	0x0a18 }, /* 0x03 */
16362306a36Sopenharmony_ci	{ TFA9879_PCM_IOM2_FORMAT_2,	0x0007 }, /* 0x04 */
16462306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_A1,		0x59dd }, /* 0x05 */
16562306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_A2,		0xc63e }, /* 0x06 */
16662306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_B1,		0x651a }, /* 0x07 */
16762306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_B2,		0xe53e }, /* 0x08 */
16862306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_C1,		0x4616 }, /* 0x09 */
16962306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_C2,		0xd33e }, /* 0x0a */
17062306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_D1,		0x4df3 }, /* 0x0b */
17162306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_D2,		0xea3e }, /* 0x0c */
17262306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_E1,		0x5ee0 }, /* 0x0d */
17362306a36Sopenharmony_ci	{ TFA9879_EQUALIZER_E2,		0xf93e }, /* 0x0e */
17462306a36Sopenharmony_ci	{ TFA9879_BYPASS_CONTROL,	0x0093 }, /* 0x0f */
17562306a36Sopenharmony_ci	{ TFA9879_DYNAMIC_RANGE_COMPR,	0x92ba }, /* 0x10 */
17662306a36Sopenharmony_ci	{ TFA9879_BASS_TREBLE,		0x12a5 }, /* 0x11 */
17762306a36Sopenharmony_ci	{ TFA9879_HIGH_PASS_FILTER,	0x0004 }, /* 0x12 */
17862306a36Sopenharmony_ci	{ TFA9879_VOLUME_CONTROL,	0x10bd }, /* 0x13 */
17962306a36Sopenharmony_ci	{ TFA9879_MISC_CONTROL,		0x0000 }, /* 0x14 */
18062306a36Sopenharmony_ci};
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistatic bool tfa9879_volatile_reg(struct device *dev, unsigned int reg)
18362306a36Sopenharmony_ci{
18462306a36Sopenharmony_ci	return reg == TFA9879_MISC_STATUS;
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(volume_tlv, -7050, 50, 1);
18862306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(tb_gain_tlv, -1800, 200, 0);
18962306a36Sopenharmony_cistatic const char * const tb_freq_text[] = {
19062306a36Sopenharmony_ci	"Low", "Mid", "High"
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_cistatic const struct soc_enum treble_freq_enum =
19362306a36Sopenharmony_ci	SOC_ENUM_SINGLE(TFA9879_BASS_TREBLE, TFA9879_F_TRBLE_SHIFT,
19462306a36Sopenharmony_ci			ARRAY_SIZE(tb_freq_text), tb_freq_text);
19562306a36Sopenharmony_cistatic const struct soc_enum bass_freq_enum =
19662306a36Sopenharmony_ci	SOC_ENUM_SINGLE(TFA9879_BASS_TREBLE, TFA9879_F_BASS_SHIFT,
19762306a36Sopenharmony_ci			ARRAY_SIZE(tb_freq_text), tb_freq_text);
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cistatic const struct snd_kcontrol_new tfa9879_controls[] = {
20062306a36Sopenharmony_ci	SOC_SINGLE_TLV("PCM Playback Volume", TFA9879_VOLUME_CONTROL,
20162306a36Sopenharmony_ci		       TFA9879_VOL_SHIFT, 0xbd, 1, volume_tlv),
20262306a36Sopenharmony_ci	SOC_SINGLE_TLV("Treble Volume", TFA9879_BASS_TREBLE,
20362306a36Sopenharmony_ci		       TFA9879_G_TRBLE_SHIFT, 18, 0, tb_gain_tlv),
20462306a36Sopenharmony_ci	SOC_SINGLE_TLV("Bass Volume", TFA9879_BASS_TREBLE,
20562306a36Sopenharmony_ci		       TFA9879_G_BASS_SHIFT, 18, 0, tb_gain_tlv),
20662306a36Sopenharmony_ci	SOC_ENUM("Treble Corner Freq", treble_freq_enum),
20762306a36Sopenharmony_ci	SOC_ENUM("Bass Corner Freq", bass_freq_enum),
20862306a36Sopenharmony_ci};
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget tfa9879_dapm_widgets[] = {
21162306a36Sopenharmony_ciSND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
21262306a36Sopenharmony_ciSND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
21362306a36Sopenharmony_ciSND_SOC_DAPM_DAC("DAC", NULL, TFA9879_DEVICE_CONTROL, TFA9879_OPMODE_SHIFT, 0),
21462306a36Sopenharmony_ciSND_SOC_DAPM_OUTPUT("LINEOUT"),
21562306a36Sopenharmony_ciSND_SOC_DAPM_SUPPLY("POWER", TFA9879_DEVICE_CONTROL, TFA9879_POWERUP_SHIFT, 0,
21662306a36Sopenharmony_ci		    NULL, 0),
21762306a36Sopenharmony_ci};
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistatic const struct snd_soc_dapm_route tfa9879_dapm_routes[] = {
22062306a36Sopenharmony_ci	{ "DAC", NULL, "AIFINL" },
22162306a36Sopenharmony_ci	{ "DAC", NULL, "AIFINR" },
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	{ "LINEOUT", NULL, "DAC" },
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	{ "DAC", NULL, "POWER" },
22662306a36Sopenharmony_ci};
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_cistatic const struct snd_soc_component_driver tfa9879_component = {
22962306a36Sopenharmony_ci	.controls		= tfa9879_controls,
23062306a36Sopenharmony_ci	.num_controls		= ARRAY_SIZE(tfa9879_controls),
23162306a36Sopenharmony_ci	.dapm_widgets		= tfa9879_dapm_widgets,
23262306a36Sopenharmony_ci	.num_dapm_widgets	= ARRAY_SIZE(tfa9879_dapm_widgets),
23362306a36Sopenharmony_ci	.dapm_routes		= tfa9879_dapm_routes,
23462306a36Sopenharmony_ci	.num_dapm_routes	= ARRAY_SIZE(tfa9879_dapm_routes),
23562306a36Sopenharmony_ci	.idle_bias_on		= 1,
23662306a36Sopenharmony_ci	.use_pmdown_time	= 1,
23762306a36Sopenharmony_ci	.endianness		= 1,
23862306a36Sopenharmony_ci};
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_cistatic const struct regmap_config tfa9879_regmap = {
24162306a36Sopenharmony_ci	.reg_bits = 8,
24262306a36Sopenharmony_ci	.val_bits = 16,
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	.volatile_reg = tfa9879_volatile_reg,
24562306a36Sopenharmony_ci	.max_register = TFA9879_MISC_STATUS,
24662306a36Sopenharmony_ci	.reg_defaults = tfa9879_regs,
24762306a36Sopenharmony_ci	.num_reg_defaults = ARRAY_SIZE(tfa9879_regs),
24862306a36Sopenharmony_ci	.cache_type = REGCACHE_RBTREE,
24962306a36Sopenharmony_ci};
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic const struct snd_soc_dai_ops tfa9879_dai_ops = {
25262306a36Sopenharmony_ci	.hw_params = tfa9879_hw_params,
25362306a36Sopenharmony_ci	.mute_stream = tfa9879_mute_stream,
25462306a36Sopenharmony_ci	.set_fmt = tfa9879_set_fmt,
25562306a36Sopenharmony_ci	.no_capture_mute = 1,
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci#define TFA9879_RATES SNDRV_PCM_RATE_8000_96000
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci#define TFA9879_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
26162306a36Sopenharmony_ci			 SNDRV_PCM_FMTBIT_S24_LE)
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_cistatic struct snd_soc_dai_driver tfa9879_dai = {
26462306a36Sopenharmony_ci	.name = "tfa9879-hifi",
26562306a36Sopenharmony_ci	.playback = {
26662306a36Sopenharmony_ci		.stream_name = "Playback",
26762306a36Sopenharmony_ci		.channels_min = 2,
26862306a36Sopenharmony_ci		.channels_max = 2,
26962306a36Sopenharmony_ci		.rates = TFA9879_RATES,
27062306a36Sopenharmony_ci		.formats = TFA9879_FORMATS, },
27162306a36Sopenharmony_ci	.ops = &tfa9879_dai_ops,
27262306a36Sopenharmony_ci};
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_cistatic int tfa9879_i2c_probe(struct i2c_client *i2c)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	struct tfa9879_priv *tfa9879;
27762306a36Sopenharmony_ci	int i;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	tfa9879 = devm_kzalloc(&i2c->dev, sizeof(*tfa9879), GFP_KERNEL);
28062306a36Sopenharmony_ci	if (!tfa9879)
28162306a36Sopenharmony_ci		return -ENOMEM;
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	i2c_set_clientdata(i2c, tfa9879);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	tfa9879->regmap = devm_regmap_init_i2c(i2c, &tfa9879_regmap);
28662306a36Sopenharmony_ci	if (IS_ERR(tfa9879->regmap))
28762306a36Sopenharmony_ci		return PTR_ERR(tfa9879->regmap);
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	/* Ensure the device is in reset state */
29062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(tfa9879_regs); i++)
29162306a36Sopenharmony_ci		regmap_write(tfa9879->regmap,
29262306a36Sopenharmony_ci			     tfa9879_regs[i].reg, tfa9879_regs[i].def);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	return devm_snd_soc_register_component(&i2c->dev, &tfa9879_component,
29562306a36Sopenharmony_ci					       &tfa9879_dai, 1);
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic const struct i2c_device_id tfa9879_i2c_id[] = {
29962306a36Sopenharmony_ci	{ "tfa9879", 0 },
30062306a36Sopenharmony_ci	{ }
30162306a36Sopenharmony_ci};
30262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, tfa9879_i2c_id);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cistatic const struct of_device_id tfa9879_of_match[] = {
30562306a36Sopenharmony_ci	{ .compatible = "nxp,tfa9879", },
30662306a36Sopenharmony_ci	{ }
30762306a36Sopenharmony_ci};
30862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, tfa9879_of_match);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_cistatic struct i2c_driver tfa9879_i2c_driver = {
31162306a36Sopenharmony_ci	.driver = {
31262306a36Sopenharmony_ci		.name = "tfa9879",
31362306a36Sopenharmony_ci		.of_match_table = tfa9879_of_match,
31462306a36Sopenharmony_ci	},
31562306a36Sopenharmony_ci	.probe = tfa9879_i2c_probe,
31662306a36Sopenharmony_ci	.id_table = tfa9879_i2c_id,
31762306a36Sopenharmony_ci};
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_cimodule_i2c_driver(tfa9879_i2c_driver);
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ciMODULE_DESCRIPTION("ASoC NXP Semiconductors TFA9879 driver");
32262306a36Sopenharmony_ciMODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
32362306a36Sopenharmony_ciMODULE_LICENSE("GPL");
324