brintos

brintos / linux-shallow public Read only

0
0
Text · 27.5 KiB · 6c6e7ae Raw
976 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * TAS571x amplifier audio driver4 *5 * Copyright (C) 2015 Google, Inc.6 * Copyright (c) 2013 Daniel Mack <zonque@gmail.com>7 *8 * TAS5721 support:9 * Copyright (C) 2016 Petr Kulhavy, Barix AG <petr@barix.com>10 *11 * TAS5707 support:12 * Copyright (C) 2018 Jerome Brunet, Baylibre SAS <jbrunet@baylibre.com>13 */14 15#include <linux/clk.h>16#include <linux/delay.h>17#include <linux/device.h>18#include <linux/gpio/consumer.h>19#include <linux/i2c.h>20#include <linux/init.h>21#include <linux/kernel.h>22#include <linux/module.h>23#include <linux/of.h>24#include <linux/regmap.h>25#include <linux/regulator/consumer.h>26#include <linux/stddef.h>27#include <sound/pcm_params.h>28#include <sound/soc.h>29#include <sound/tlv.h>30#include <linux/unaligned.h>31 32#include "tas571x.h"33 34#define TAS571X_MAX_SUPPLIES		635 36struct tas571x_chip {37	const char			*const *supply_names;38	int				num_supply_names;39	const struct snd_kcontrol_new	*controls;40	int				num_controls;41	const struct regmap_config	*regmap_config;42	int				vol_reg_size;43};44 45struct tas571x_private {46	const struct tas571x_chip	*chip;47	struct regmap			*regmap;48	struct regulator_bulk_data	supplies[TAS571X_MAX_SUPPLIES];49	struct clk			*mclk;50	unsigned int			format;51	struct gpio_desc		*reset_gpio;52	struct gpio_desc		*pdn_gpio;53	struct snd_soc_component_driver	component_driver;54};55 56static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)57{58	switch (reg) {59	case TAS571X_MVOL_REG:60	case TAS571X_CH1_VOL_REG:61	case TAS571X_CH2_VOL_REG:62		return priv->chip->vol_reg_size;63	case TAS571X_INPUT_MUX_REG:64	case TAS571X_CH4_SRC_SELECT_REG:65	case TAS571X_PWM_MUX_REG:66	case TAS5717_CH1_RIGHT_CH_MIX_REG:67	case TAS5717_CH1_LEFT_CH_MIX_REG:68	case TAS5717_CH2_LEFT_CH_MIX_REG:69	case TAS5717_CH2_RIGHT_CH_MIX_REG:70		return 4;71	default:72		return 1;73	}74}75 76static int tas571x_reg_write(void *context, unsigned int reg,77			     unsigned int value)78{79	struct i2c_client *client = context;80	struct tas571x_private *priv = i2c_get_clientdata(client);81	unsigned int i, size;82	uint8_t buf[5];83	int ret;84 85	size = tas571x_register_size(priv, reg);86	buf[0] = reg;87 88	for (i = size; i >= 1; --i) {89		buf[i] = value;90		value >>= 8;91	}92 93	ret = i2c_master_send(client, buf, size + 1);94	if (ret == size + 1)95		return 0;96	else if (ret < 0)97		return ret;98	else99		return -EIO;100}101 102static int tas571x_reg_read(void *context, unsigned int reg,103			    unsigned int *value)104{105	struct i2c_client *client = context;106	struct tas571x_private *priv = i2c_get_clientdata(client);107	uint8_t send_buf, recv_buf[4];108	struct i2c_msg msgs[2];109	unsigned int size;110	unsigned int i;111	int ret;112 113	size = tas571x_register_size(priv, reg);114	send_buf = reg;115 116	msgs[0].addr = client->addr;117	msgs[0].len = sizeof(send_buf);118	msgs[0].buf = &send_buf;119	msgs[0].flags = 0;120 121	msgs[1].addr = client->addr;122	msgs[1].len = size;123	msgs[1].buf = recv_buf;124	msgs[1].flags = I2C_M_RD;125 126	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));127	if (ret < 0)128		return ret;129	else if (ret != ARRAY_SIZE(msgs))130		return -EIO;131 132	*value = 0;133 134	for (i = 0; i < size; i++) {135		*value <<= 8;136		*value |= recv_buf[i];137	}138 139	return 0;140}141 142/*143 * register write for 8- and 20-byte registers144 */145static int tas571x_reg_write_multiword(struct i2c_client *client,146		unsigned int reg, const long values[], size_t len)147{148	size_t i;149	uint8_t *buf, *p;150	int ret;151	size_t send_size = 1 + len * sizeof(uint32_t);152 153	buf = kzalloc(send_size, GFP_KERNEL | GFP_DMA);154	if (!buf)155		return -ENOMEM;156	buf[0] = reg;157 158	for (i = 0, p = buf + 1; i < len; i++, p += sizeof(uint32_t))159		put_unaligned_be32(values[i], p);160 161	ret = i2c_master_send(client, buf, send_size);162 163	kfree(buf);164 165	if (ret == send_size)166		return 0;167	else if (ret < 0)168		return ret;169	else170		return -EIO;171}172 173/*174 * register read for 8- and 20-byte registers175 */176static int tas571x_reg_read_multiword(struct i2c_client *client,177		unsigned int reg, long values[], size_t len)178{179	unsigned int i;180	uint8_t send_buf;181	uint8_t *recv_buf, *p;182	struct i2c_msg msgs[2];183	unsigned int recv_size = len * sizeof(uint32_t);184	int ret;185 186	recv_buf = kzalloc(recv_size, GFP_KERNEL | GFP_DMA);187	if (!recv_buf)188		return -ENOMEM;189 190	send_buf = reg;191 192	msgs[0].addr = client->addr;193	msgs[0].len = sizeof(send_buf);194	msgs[0].buf = &send_buf;195	msgs[0].flags = 0;196 197	msgs[1].addr = client->addr;198	msgs[1].len = recv_size;199	msgs[1].buf = recv_buf;200	msgs[1].flags = I2C_M_RD;201 202	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));203	if (ret < 0)204		goto err_ret;205	else if (ret != ARRAY_SIZE(msgs)) {206		ret = -EIO;207		goto err_ret;208	}209 210	for (i = 0, p = recv_buf; i < len; i++, p += sizeof(uint32_t))211		values[i] = get_unaligned_be32(p);212 213err_ret:214	kfree(recv_buf);215	return ret;216}217 218/*219 * Integer array controls for setting biquad, mixer, DRC coefficients.220 * According to the datasheet each coefficient is effectively 26bits,221 * i.e. stored as 32bits, where bits [31:26] are ignored.222 * TI's TAS57xx Graphical Development Environment tool however produces223 * coefficients with more than 26 bits. For this reason we allow values224 * in the full 32-bits reange.225 * The coefficients are ordered as given in the TAS571x data sheet:226 * b0, b1, b2, a1, a2227 */228 229static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,230				   struct snd_ctl_elem_info *uinfo)231{232	int numcoef = kcontrol->private_value >> 16;233 234	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;235	uinfo->count = numcoef;236	uinfo->value.integer.min = 0;237	uinfo->value.integer.max = 0xffffffff;238	return 0;239}240 241static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,242				  struct snd_ctl_elem_value *ucontrol)243{244	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);245	struct i2c_client *i2c = to_i2c_client(component->dev);246	int numcoef = kcontrol->private_value >> 16;247	int index = kcontrol->private_value & 0xffff;248 249	return tas571x_reg_read_multiword(i2c, index,250		ucontrol->value.integer.value, numcoef);251}252 253static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,254				  struct snd_ctl_elem_value *ucontrol)255{256	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);257	struct i2c_client *i2c = to_i2c_client(component->dev);258	int numcoef = kcontrol->private_value >> 16;259	int index = kcontrol->private_value & 0xffff;260 261	return tas571x_reg_write_multiword(i2c, index,262		ucontrol->value.integer.value, numcoef);263}264 265static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)266{267	struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);268 269	priv->format = format;270 271	return 0;272}273 274static int tas571x_hw_params(struct snd_pcm_substream *substream,275			     struct snd_pcm_hw_params *params,276			     struct snd_soc_dai *dai)277{278	struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);279	u32 val;280 281	switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {282	case SND_SOC_DAIFMT_RIGHT_J:283		val = 0x00;284		break;285	case SND_SOC_DAIFMT_I2S:286		val = 0x03;287		break;288	case SND_SOC_DAIFMT_LEFT_J:289		val = 0x06;290		break;291	default:292		return -EINVAL;293	}294 295	if (params_width(params) >= 24)296		val += 2;297	else if (params_width(params) >= 20)298		val += 1;299 300	return regmap_update_bits(priv->regmap, TAS571X_SDI_REG,301				  TAS571X_SDI_FMT_MASK, val);302}303 304static int tas571x_mute(struct snd_soc_dai *dai, int mute, int direction)305{306	struct snd_soc_component *component = dai->component;307	u8 sysctl2;308	int ret;309 310	sysctl2 = mute ? TAS571X_SYS_CTRL_2_SDN_MASK : 0;311 312	ret = snd_soc_component_update_bits(component,313			    TAS571X_SYS_CTRL_2_REG,314		     TAS571X_SYS_CTRL_2_SDN_MASK,315		     sysctl2);316	usleep_range(1000, 2000);317 318	return ret;319}320 321static int tas571x_set_bias_level(struct snd_soc_component *component,322				  enum snd_soc_bias_level level)323{324	struct tas571x_private *priv = snd_soc_component_get_drvdata(component);325	int ret;326 327	switch (level) {328	case SND_SOC_BIAS_ON:329		break;330	case SND_SOC_BIAS_PREPARE:331		break;332	case SND_SOC_BIAS_STANDBY:333		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {334			if (!IS_ERR(priv->mclk)) {335				ret = clk_prepare_enable(priv->mclk);336				if (ret) {337					dev_err(component->dev,338						"Failed to enable master clock: %d\n",339						ret);340					return ret;341				}342			}343		}344		break;345	case SND_SOC_BIAS_OFF:346		if (!IS_ERR(priv->mclk))347			clk_disable_unprepare(priv->mclk);348		break;349	}350 351	return 0;352}353 354static const struct snd_soc_dai_ops tas571x_dai_ops = {355	.set_fmt	= tas571x_set_dai_fmt,356	.hw_params	= tas571x_hw_params,357	.mute_stream	= tas571x_mute,358	.no_capture_mute = 1,359};360 361 362#define BIQUAD_COEFS(xname, reg) \363{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \364	.info = tas571x_coefficient_info, \365	.get = tas571x_coefficient_get,\366	.put = tas571x_coefficient_put, \367	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \368	.private_value = reg | (5 << 16) }369 370static const char *const tas5711_supply_names[] = {371	"AVDD",372	"DVDD",373	"PVDD_A",374	"PVDD_B",375	"PVDD_C",376	"PVDD_D",377};378 379static const DECLARE_TLV_DB_SCALE(tas5711_volume_tlv, -10350, 50, 1);380 381static const struct snd_kcontrol_new tas5711_controls[] = {382	SOC_SINGLE_TLV("Master Volume",383		       TAS571X_MVOL_REG,384		       0, 0xff, 1, tas5711_volume_tlv),385	SOC_DOUBLE_R_TLV("Speaker Volume",386			 TAS571X_CH1_VOL_REG,387			 TAS571X_CH2_VOL_REG,388			 0, 0xff, 1, tas5711_volume_tlv),389	SOC_DOUBLE("Speaker Switch",390		   TAS571X_SOFT_MUTE_REG,391		   TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,392		   1, 1),393};394 395static const struct regmap_range tas571x_readonly_regs_range[] = {396	regmap_reg_range(TAS571X_CLK_CTRL_REG,  TAS571X_DEV_ID_REG),397};398 399static const struct regmap_range tas571x_volatile_regs_range[] = {400	regmap_reg_range(TAS571X_CLK_CTRL_REG,  TAS571X_ERR_STATUS_REG),401	regmap_reg_range(TAS571X_OSC_TRIM_REG,  TAS571X_OSC_TRIM_REG),402};403 404static const struct regmap_access_table tas571x_write_regs = {405	.no_ranges =	tas571x_readonly_regs_range,406	.n_no_ranges =	ARRAY_SIZE(tas571x_readonly_regs_range),407};408 409static const struct regmap_access_table tas571x_volatile_regs = {410	.yes_ranges =	tas571x_volatile_regs_range,411	.n_yes_ranges =	ARRAY_SIZE(tas571x_volatile_regs_range),412 413};414 415static const struct reg_default tas5711_reg_defaults[] = {416	{ 0x04, 0x05 },417	{ 0x05, 0x40 },418	{ 0x06, 0x00 },419	{ 0x07, 0xff },420	{ 0x08, 0x30 },421	{ 0x09, 0x30 },422	{ 0x1b, 0x82 },423};424 425static const struct regmap_config tas5711_regmap_config = {426	.reg_bits			= 8,427	.val_bits			= 32,428	.max_register			= 0xff,429	.reg_read			= tas571x_reg_read,430	.reg_write			= tas571x_reg_write,431	.reg_defaults			= tas5711_reg_defaults,432	.num_reg_defaults		= ARRAY_SIZE(tas5711_reg_defaults),433	.cache_type			= REGCACHE_RBTREE,434	.wr_table			= &tas571x_write_regs,435	.volatile_table			= &tas571x_volatile_regs,436};437 438static const struct tas571x_chip tas5711_chip = {439	.supply_names			= tas5711_supply_names,440	.num_supply_names		= ARRAY_SIZE(tas5711_supply_names),441	.controls			= tas5711_controls,442	.num_controls			= ARRAY_SIZE(tas5711_controls),443	.regmap_config			= &tas5711_regmap_config,444	.vol_reg_size			= 1,445};446 447static const struct regmap_range tas5707_volatile_regs_range[] = {448	regmap_reg_range(TAS571X_CLK_CTRL_REG,  TAS571X_ERR_STATUS_REG),449	regmap_reg_range(TAS571X_OSC_TRIM_REG,  TAS571X_OSC_TRIM_REG),450	regmap_reg_range(TAS5707_CH1_BQ0_REG, TAS5707_CH2_BQ6_REG),451};452 453static const struct regmap_access_table tas5707_volatile_regs = {454	.yes_ranges =	tas5707_volatile_regs_range,455	.n_yes_ranges =	ARRAY_SIZE(tas5707_volatile_regs_range),456 457};458 459static const DECLARE_TLV_DB_SCALE(tas5707_volume_tlv, -7900, 50, 1);460 461static const char * const tas5707_volume_slew_step_txt[] = {462	"256", "512", "1024", "2048",463};464 465static const unsigned int tas5707_volume_slew_step_values[] = {466	3, 0, 1, 2,467};468 469static SOC_VALUE_ENUM_SINGLE_DECL(tas5707_volume_slew_step_enum,470				  TAS571X_VOL_CFG_REG, 0, 0x3,471				  tas5707_volume_slew_step_txt,472				  tas5707_volume_slew_step_values);473 474static const struct snd_kcontrol_new tas5707_controls[] = {475	SOC_SINGLE_TLV("Master Volume",476		       TAS571X_MVOL_REG,477		       0, 0xff, 1, tas5707_volume_tlv),478	SOC_DOUBLE_R_TLV("Speaker Volume",479			 TAS571X_CH1_VOL_REG,480			 TAS571X_CH2_VOL_REG,481			 0, 0xff, 1, tas5707_volume_tlv),482	SOC_DOUBLE("Speaker Switch",483		   TAS571X_SOFT_MUTE_REG,484		   TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,485		   1, 1),486 487	SOC_ENUM("Slew Rate Steps", tas5707_volume_slew_step_enum),488 489	BIQUAD_COEFS("CH1 - Biquad 0", TAS5707_CH1_BQ0_REG),490	BIQUAD_COEFS("CH1 - Biquad 1", TAS5707_CH1_BQ1_REG),491	BIQUAD_COEFS("CH1 - Biquad 2", TAS5707_CH1_BQ2_REG),492	BIQUAD_COEFS("CH1 - Biquad 3", TAS5707_CH1_BQ3_REG),493	BIQUAD_COEFS("CH1 - Biquad 4", TAS5707_CH1_BQ4_REG),494	BIQUAD_COEFS("CH1 - Biquad 5", TAS5707_CH1_BQ5_REG),495	BIQUAD_COEFS("CH1 - Biquad 6", TAS5707_CH1_BQ6_REG),496 497	BIQUAD_COEFS("CH2 - Biquad 0", TAS5707_CH2_BQ0_REG),498	BIQUAD_COEFS("CH2 - Biquad 1", TAS5707_CH2_BQ1_REG),499	BIQUAD_COEFS("CH2 - Biquad 2", TAS5707_CH2_BQ2_REG),500	BIQUAD_COEFS("CH2 - Biquad 3", TAS5707_CH2_BQ3_REG),501	BIQUAD_COEFS("CH2 - Biquad 4", TAS5707_CH2_BQ4_REG),502	BIQUAD_COEFS("CH2 - Biquad 5", TAS5707_CH2_BQ5_REG),503	BIQUAD_COEFS("CH2 - Biquad 6", TAS5707_CH2_BQ6_REG),504};505 506static const struct reg_default tas5707_reg_defaults[] = {507	{TAS571X_CLK_CTRL_REG,		0x6c},508	{TAS571X_DEV_ID_REG,		0x70},509	{TAS571X_ERR_STATUS_REG,	0x00},510	{TAS571X_SYS_CTRL_1_REG,	0xa0},511	{TAS571X_SDI_REG,		0x05},512	{TAS571X_SYS_CTRL_2_REG,	0x40},513	{TAS571X_SOFT_MUTE_REG,		0x00},514	{TAS571X_MVOL_REG,		0xff},515	{TAS571X_CH1_VOL_REG,		0x30},516	{TAS571X_CH2_VOL_REG,		0x30},517	{TAS571X_VOL_CFG_REG,		0x91},518	{TAS571X_MODULATION_LIMIT_REG,	0x02},519	{TAS571X_IC_DELAY_CH1_REG,	0xac},520	{TAS571X_IC_DELAY_CH2_REG,	0x54},521	{TAS571X_IC_DELAY_CH3_REG,	0xac},522	{TAS571X_IC_DELAY_CH4_REG,	0x54},523	{TAS571X_START_STOP_PERIOD_REG,	0x0f},524	{TAS571X_OSC_TRIM_REG,		0x82},525	{TAS571X_BKND_ERR_REG,		0x02},526	{TAS571X_INPUT_MUX_REG,		0x17772},527	{TAS571X_PWM_MUX_REG,		0x1021345},528};529 530static const struct regmap_config tas5707_regmap_config = {531	.reg_bits			= 8,532	.val_bits			= 32,533	.max_register			= 0xff,534	.reg_read			= tas571x_reg_read,535	.reg_write			= tas571x_reg_write,536	.reg_defaults			= tas5707_reg_defaults,537	.num_reg_defaults		= ARRAY_SIZE(tas5707_reg_defaults),538	.cache_type			= REGCACHE_RBTREE,539	.wr_table			= &tas571x_write_regs,540	.volatile_table			= &tas5707_volatile_regs,541};542 543static const struct tas571x_chip tas5707_chip = {544	.supply_names			= tas5711_supply_names,545	.num_supply_names		= ARRAY_SIZE(tas5711_supply_names),546	.controls			= tas5707_controls,547	.num_controls			= ARRAY_SIZE(tas5707_controls),548	.regmap_config			= &tas5707_regmap_config,549	.vol_reg_size			= 1,550};551 552static const char *const tas5717_supply_names[] = {553	"AVDD",554	"DVDD",555	"HPVDD",556	"PVDD_AB",557	"PVDD_CD",558};559 560static const DECLARE_TLV_DB_SCALE(tas5717_volume_tlv, -10375, 25, 0);561 562static const struct snd_kcontrol_new tas5717_controls[] = {563	/* MVOL LSB is ignored - see comments in tas571x_i2c_probe() */564	SOC_SINGLE_TLV("Master Volume",565		       TAS571X_MVOL_REG, 1, 0x1ff, 1,566		       tas5717_volume_tlv),567	SOC_DOUBLE_R_TLV("Speaker Volume",568			 TAS571X_CH1_VOL_REG, TAS571X_CH2_VOL_REG,569			 1, 0x1ff, 1, tas5717_volume_tlv),570	SOC_DOUBLE("Speaker Switch",571		   TAS571X_SOFT_MUTE_REG,572		   TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,573		   1, 1),574 575	SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",576			   TAS5717_CH1_LEFT_CH_MIX_REG,577			   TAS5717_CH1_RIGHT_CH_MIX_REG,578			   16, 0, 0x80, 0),579 580	SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",581			   TAS5717_CH2_LEFT_CH_MIX_REG,582			   TAS5717_CH2_RIGHT_CH_MIX_REG,583			   16, 0, 0x80, 0),584 585	/*586	 * The biquads are named according to the register names.587	 * Please note that TI's TAS57xx Graphical Development Environment588	 * tool names them different.589	 */590	BIQUAD_COEFS("CH1 - Biquad 0", TAS5717_CH1_BQ0_REG),591	BIQUAD_COEFS("CH1 - Biquad 1", TAS5717_CH1_BQ1_REG),592	BIQUAD_COEFS("CH1 - Biquad 2", TAS5717_CH1_BQ2_REG),593	BIQUAD_COEFS("CH1 - Biquad 3", TAS5717_CH1_BQ3_REG),594	BIQUAD_COEFS("CH1 - Biquad 4", TAS5717_CH1_BQ4_REG),595	BIQUAD_COEFS("CH1 - Biquad 5", TAS5717_CH1_BQ5_REG),596	BIQUAD_COEFS("CH1 - Biquad 6", TAS5717_CH1_BQ6_REG),597	BIQUAD_COEFS("CH1 - Biquad 7", TAS5717_CH1_BQ7_REG),598	BIQUAD_COEFS("CH1 - Biquad 8", TAS5717_CH1_BQ8_REG),599	BIQUAD_COEFS("CH1 - Biquad 9", TAS5717_CH1_BQ9_REG),600	BIQUAD_COEFS("CH1 - Biquad 10", TAS5717_CH1_BQ10_REG),601	BIQUAD_COEFS("CH1 - Biquad 11", TAS5717_CH1_BQ11_REG),602 603	BIQUAD_COEFS("CH2 - Biquad 0", TAS5717_CH2_BQ0_REG),604	BIQUAD_COEFS("CH2 - Biquad 1", TAS5717_CH2_BQ1_REG),605	BIQUAD_COEFS("CH2 - Biquad 2", TAS5717_CH2_BQ2_REG),606	BIQUAD_COEFS("CH2 - Biquad 3", TAS5717_CH2_BQ3_REG),607	BIQUAD_COEFS("CH2 - Biquad 4", TAS5717_CH2_BQ4_REG),608	BIQUAD_COEFS("CH2 - Biquad 5", TAS5717_CH2_BQ5_REG),609	BIQUAD_COEFS("CH2 - Biquad 6", TAS5717_CH2_BQ6_REG),610	BIQUAD_COEFS("CH2 - Biquad 7", TAS5717_CH2_BQ7_REG),611	BIQUAD_COEFS("CH2 - Biquad 8", TAS5717_CH2_BQ8_REG),612	BIQUAD_COEFS("CH2 - Biquad 9", TAS5717_CH2_BQ9_REG),613	BIQUAD_COEFS("CH2 - Biquad 10", TAS5717_CH2_BQ10_REG),614	BIQUAD_COEFS("CH2 - Biquad 11", TAS5717_CH2_BQ11_REG),615 616	BIQUAD_COEFS("CH3 - Biquad 0", TAS5717_CH3_BQ0_REG),617	BIQUAD_COEFS("CH3 - Biquad 1", TAS5717_CH3_BQ1_REG),618 619	BIQUAD_COEFS("CH4 - Biquad 0", TAS5717_CH4_BQ0_REG),620	BIQUAD_COEFS("CH4 - Biquad 1", TAS5717_CH4_BQ1_REG),621};622 623static const struct reg_default tas5717_reg_defaults[] = {624	{ 0x04, 0x05 },625	{ 0x05, 0x40 },626	{ 0x06, 0x00 },627	{ 0x07, 0x03ff },628	{ 0x08, 0x00c0 },629	{ 0x09, 0x00c0 },630	{ 0x1b, 0x82 },631	{ TAS5717_CH1_RIGHT_CH_MIX_REG, 0x0 },632	{ TAS5717_CH1_LEFT_CH_MIX_REG, 0x800000},633	{ TAS5717_CH2_LEFT_CH_MIX_REG, 0x0 },634	{ TAS5717_CH2_RIGHT_CH_MIX_REG, 0x800000},635};636 637static const struct regmap_config tas5717_regmap_config = {638	.reg_bits			= 8,639	.val_bits			= 32,640	.max_register			= 0xff,641	.reg_read			= tas571x_reg_read,642	.reg_write			= tas571x_reg_write,643	.reg_defaults			= tas5717_reg_defaults,644	.num_reg_defaults		= ARRAY_SIZE(tas5717_reg_defaults),645	.cache_type			= REGCACHE_RBTREE,646	.wr_table			= &tas571x_write_regs,647	.volatile_table			= &tas571x_volatile_regs,648};649 650/* This entry is reused for tas5719 as the software interface is identical. */651static const struct tas571x_chip tas5717_chip = {652	.supply_names			= tas5717_supply_names,653	.num_supply_names		= ARRAY_SIZE(tas5717_supply_names),654	.controls			= tas5717_controls,655	.num_controls			= ARRAY_SIZE(tas5717_controls),656	.regmap_config			= &tas5717_regmap_config,657	.vol_reg_size			= 2,658};659 660static const char *const tas5721_supply_names[] = {661	"AVDD",662	"DVDD",663	"DRVDD",664	"PVDD",665};666 667static const struct snd_kcontrol_new tas5721_controls[] = {668	SOC_SINGLE_TLV("Master Volume",669		       TAS571X_MVOL_REG,670		       0, 0xff, 1, tas5711_volume_tlv),671	SOC_DOUBLE_R_TLV("Speaker Volume",672			 TAS571X_CH1_VOL_REG,673			 TAS571X_CH2_VOL_REG,674			 0, 0xff, 1, tas5711_volume_tlv),675	SOC_DOUBLE("Speaker Switch",676		   TAS571X_SOFT_MUTE_REG,677		   TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,678		   1, 1),679};680 681static const struct reg_default tas5721_reg_defaults[] = {682	{TAS571X_CLK_CTRL_REG,		0x6c},683	{TAS571X_DEV_ID_REG,		0x00},684	{TAS571X_ERR_STATUS_REG,	0x00},685	{TAS571X_SYS_CTRL_1_REG,	0xa0},686	{TAS571X_SDI_REG,		0x05},687	{TAS571X_SYS_CTRL_2_REG,	0x40},688	{TAS571X_SOFT_MUTE_REG,		0x00},689	{TAS571X_MVOL_REG,		0xff},690	{TAS571X_CH1_VOL_REG,		0x30},691	{TAS571X_CH2_VOL_REG,		0x30},692	{TAS571X_CH3_VOL_REG,		0x30},693	{TAS571X_VOL_CFG_REG,		0x91},694	{TAS571X_MODULATION_LIMIT_REG,	0x02},695	{TAS571X_IC_DELAY_CH1_REG,	0xac},696	{TAS571X_IC_DELAY_CH2_REG,	0x54},697	{TAS571X_IC_DELAY_CH3_REG,	0xac},698	{TAS571X_IC_DELAY_CH4_REG,	0x54},699	{TAS571X_PWM_CH_SDN_GROUP_REG,	0x30},700	{TAS571X_START_STOP_PERIOD_REG,	0x0f},701	{TAS571X_OSC_TRIM_REG,		0x82},702	{TAS571X_BKND_ERR_REG,		0x02},703	{TAS571X_INPUT_MUX_REG,		0x17772},704	{TAS571X_CH4_SRC_SELECT_REG,	0x4303},705	{TAS571X_PWM_MUX_REG,		0x1021345},706};707 708static const struct regmap_config tas5721_regmap_config = {709	.reg_bits			= 8,710	.val_bits			= 32,711	.max_register			= 0xff,712	.reg_read			= tas571x_reg_read,713	.reg_write			= tas571x_reg_write,714	.reg_defaults			= tas5721_reg_defaults,715	.num_reg_defaults		= ARRAY_SIZE(tas5721_reg_defaults),716	.cache_type			= REGCACHE_RBTREE,717	.wr_table			= &tas571x_write_regs,718	.volatile_table			= &tas571x_volatile_regs,719};720 721static const char *const tas5733_supply_names[] = {722	"AVDD",723	"DVDD",724	"PVDD",725};726 727static const struct reg_default tas5733_reg_defaults[] = {728	{TAS571X_CLK_CTRL_REG,          0x6c},729	{TAS571X_DEV_ID_REG,            0x00},730	{TAS571X_ERR_STATUS_REG,        0x00},731	{TAS571X_SYS_CTRL_1_REG,        0xa0},732	{TAS571X_SDI_REG,               0x05},733	{TAS571X_SYS_CTRL_2_REG,        0x40},734	{TAS571X_SOFT_MUTE_REG,         0x07},735	{TAS571X_MVOL_REG,              0x03ff},736	{TAS571X_CH1_VOL_REG,           0x00c0},737	{TAS571X_CH2_VOL_REG,           0x00c0},738	{TAS571X_CH3_VOL_REG,           0x00c0},739	{TAS571X_VOL_CFG_REG,           0xf0},740	{TAS571X_MODULATION_LIMIT_REG,  0x07},741	{TAS571X_IC_DELAY_CH1_REG,      0xb8},742	{TAS571X_IC_DELAY_CH2_REG,      0x60},743	{TAS571X_IC_DELAY_CH3_REG,      0xa0},744	{TAS571X_IC_DELAY_CH4_REG,      0x48},745	{TAS571X_PWM_CH_SDN_GROUP_REG,  0x30},746	{TAS571X_START_STOP_PERIOD_REG, 0x68},747	{TAS571X_OSC_TRIM_REG,          0x82},748	{TAS571X_BKND_ERR_REG,          0x02},749	{TAS571X_INPUT_MUX_REG,         0x00897772},750	{TAS571X_PWM_MUX_REG,           0x01021345},751	{TAS5717_CH1_RIGHT_CH_MIX_REG,  0x00},752	{TAS5717_CH1_LEFT_CH_MIX_REG,   0x800000},753	{TAS5717_CH2_LEFT_CH_MIX_REG,   0x00},754	{TAS5717_CH2_RIGHT_CH_MIX_REG,  0x800000},755};756 757static const struct regmap_config tas5733_regmap_config = {758	.reg_bits                       = 8,759	.val_bits                       = 32,760	.max_register                   = 0xff,761	.reg_read                       = tas571x_reg_read,762	.reg_write                      = tas571x_reg_write,763	.reg_defaults                   = tas5733_reg_defaults,764	.num_reg_defaults               = ARRAY_SIZE(tas5733_reg_defaults),765	.cache_type                     = REGCACHE_RBTREE,766	.wr_table                       = &tas571x_write_regs,767	.volatile_table                 = &tas571x_volatile_regs,768};769 770static const struct tas571x_chip tas5733_chip = {771	.supply_names                   = tas5733_supply_names,772	.num_supply_names               = ARRAY_SIZE(tas5733_supply_names),773	.controls                       = tas5717_controls,774	.num_controls                   = ARRAY_SIZE(tas5717_controls),775	.regmap_config                  = &tas5733_regmap_config,776	.vol_reg_size                   = 2,777};778 779static const struct tas571x_chip tas5721_chip = {780	.supply_names			= tas5721_supply_names,781	.num_supply_names		= ARRAY_SIZE(tas5721_supply_names),782	.controls			= tas5721_controls,783	.num_controls			= ARRAY_SIZE(tas5721_controls),784	.regmap_config			= &tas5721_regmap_config,785	.vol_reg_size			= 1,786};787 788static const struct snd_soc_dapm_widget tas571x_dapm_widgets[] = {789	SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),790	SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),791 792	SND_SOC_DAPM_OUTPUT("OUT_A"),793	SND_SOC_DAPM_OUTPUT("OUT_B"),794	SND_SOC_DAPM_OUTPUT("OUT_C"),795	SND_SOC_DAPM_OUTPUT("OUT_D"),796};797 798static const struct snd_soc_dapm_route tas571x_dapm_routes[] = {799	{ "DACL",  NULL, "Playback" },800	{ "DACR",  NULL, "Playback" },801 802	{ "OUT_A", NULL, "DACL" },803	{ "OUT_B", NULL, "DACL" },804	{ "OUT_C", NULL, "DACR" },805	{ "OUT_D", NULL, "DACR" },806};807 808static const struct snd_soc_component_driver tas571x_component = {809	.set_bias_level		= tas571x_set_bias_level,810	.dapm_widgets		= tas571x_dapm_widgets,811	.num_dapm_widgets	= ARRAY_SIZE(tas571x_dapm_widgets),812	.dapm_routes		= tas571x_dapm_routes,813	.num_dapm_routes	= ARRAY_SIZE(tas571x_dapm_routes),814	.use_pmdown_time	= 1,815	.endianness		= 1,816};817 818static struct snd_soc_dai_driver tas571x_dai = {819	.name = "tas571x-hifi",820	.playback = {821		.stream_name = "Playback",822		.channels_min = 2,823		.channels_max = 2,824		.rates = SNDRV_PCM_RATE_8000_48000,825		.formats = SNDRV_PCM_FMTBIT_S32_LE |826			   SNDRV_PCM_FMTBIT_S24_LE |827			   SNDRV_PCM_FMTBIT_S16_LE,828	},829	.ops = &tas571x_dai_ops,830};831 832static int tas571x_i2c_probe(struct i2c_client *client)833{834	struct tas571x_private *priv;835	struct device *dev = &client->dev;836	int i, ret;837 838	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);839	if (!priv)840		return -ENOMEM;841	i2c_set_clientdata(client, priv);842 843	priv->chip = i2c_get_match_data(client);844 845	priv->mclk = devm_clk_get(dev, "mclk");846	if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) {847		dev_err(dev, "Failed to request mclk: %ld\n",848			PTR_ERR(priv->mclk));849		return PTR_ERR(priv->mclk);850	}851 852	if (WARN_ON(priv->chip->num_supply_names > TAS571X_MAX_SUPPLIES))853		return -EINVAL;854	for (i = 0; i < priv->chip->num_supply_names; i++)855		priv->supplies[i].supply = priv->chip->supply_names[i];856 857	ret = devm_regulator_bulk_get(dev, priv->chip->num_supply_names,858				      priv->supplies);859	if (ret) {860		dev_err(dev, "Failed to get supplies: %d\n", ret);861		return ret;862	}863	ret = regulator_bulk_enable(priv->chip->num_supply_names,864				    priv->supplies);865	if (ret) {866		dev_err(dev, "Failed to enable supplies: %d\n", ret);867		return ret;868	}869 870	priv->regmap = devm_regmap_init(dev, NULL, client,871					priv->chip->regmap_config);872	if (IS_ERR(priv->regmap)) {873		ret = PTR_ERR(priv->regmap);874		goto disable_regs;875	}876 877	priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW);878	if (IS_ERR(priv->pdn_gpio)) {879		dev_err(dev, "error requesting pdn_gpio: %ld\n",880			PTR_ERR(priv->pdn_gpio));881		ret = PTR_ERR(priv->pdn_gpio);882		goto disable_regs;883	}884 885	priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",886						   GPIOD_OUT_HIGH);887	if (IS_ERR(priv->reset_gpio)) {888		dev_err(dev, "error requesting reset_gpio: %ld\n",889			PTR_ERR(priv->reset_gpio));890		ret = PTR_ERR(priv->reset_gpio);891		goto disable_regs;892	} else if (priv->reset_gpio) {893		/* pulse the active low reset line for ~100us */894		usleep_range(100, 200);895		gpiod_set_value(priv->reset_gpio, 0);896		usleep_range(13500, 20000);897	}898 899	ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);900	if (ret)901		goto disable_regs;902 903	usleep_range(50000, 60000);904 905	memcpy(&priv->component_driver, &tas571x_component, sizeof(priv->component_driver));906	priv->component_driver.controls = priv->chip->controls;907	priv->component_driver.num_controls = priv->chip->num_controls;908 909	if (priv->chip->vol_reg_size == 2) {910		/*911		 * The master volume defaults to 0x3ff (mute), but we ignore912		 * (zero) the LSB because the hardware step size is 0.125 dB913		 * and TLV_DB_SCALE_ITEM has a resolution of 0.01 dB.914		 */915		ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0);916		if (ret)917			goto disable_regs;918	}919 920	ret = devm_snd_soc_register_component(&client->dev,921				      &priv->component_driver,922				      &tas571x_dai, 1);923	if (ret)924		goto disable_regs;925 926	return ret;927 928disable_regs:929	regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);930	return ret;931}932 933static void tas571x_i2c_remove(struct i2c_client *client)934{935	struct tas571x_private *priv = i2c_get_clientdata(client);936 937	regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);938}939 940static const struct of_device_id tas571x_of_match[] __maybe_unused = {941	{ .compatible = "ti,tas5707", .data = &tas5707_chip, },942	{ .compatible = "ti,tas5711", .data = &tas5711_chip, },943	{ .compatible = "ti,tas5717", .data = &tas5717_chip, },944	{ .compatible = "ti,tas5719", .data = &tas5717_chip, },945	{ .compatible = "ti,tas5721", .data = &tas5721_chip, },946	{ .compatible = "ti,tas5733", .data = &tas5733_chip, },947	{ }948};949MODULE_DEVICE_TABLE(of, tas571x_of_match);950 951static const struct i2c_device_id tas571x_i2c_id[] = {952	{ "tas5707", (kernel_ulong_t) &tas5707_chip },953	{ "tas5711", (kernel_ulong_t) &tas5711_chip },954	{ "tas5717", (kernel_ulong_t) &tas5717_chip },955	{ "tas5719", (kernel_ulong_t) &tas5717_chip },956	{ "tas5721", (kernel_ulong_t) &tas5721_chip },957	{ "tas5733", (kernel_ulong_t) &tas5733_chip },958	{ }959};960MODULE_DEVICE_TABLE(i2c, tas571x_i2c_id);961 962static struct i2c_driver tas571x_i2c_driver = {963	.driver = {964		.name = "tas571x",965		.of_match_table = of_match_ptr(tas571x_of_match),966	},967	.probe = tas571x_i2c_probe,968	.remove = tas571x_i2c_remove,969	.id_table = tas571x_i2c_id,970};971module_i2c_driver(tas571x_i2c_driver);972 973MODULE_DESCRIPTION("ASoC TAS571x driver");974MODULE_AUTHOR("Kevin Cernekee <cernekee@chromium.org>");975MODULE_LICENSE("GPL");976