/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __TAS2764_QUIRKS__
#define __TAS2764_QUIRKS__
#include <linux/regmap.h>
#include "tas2764.h"
/* Bitmask of enabled Apple quirks */
#define ENABLED_APPLE_QUIRKS 0 x3f
/*
* Disable noise gate and flip down reserved bit in NS_CFG0
*/
#define TAS2764_NOISE_GATE_DISABLE BIT(0 )
static const struct reg_sequence tas2764_noise_gate_dis_seq[] = {
REG_SEQ0(TAS2764_REG(0 x0, 0 x35), 0 xb0)
};
/*
* CONV_VBAT_PVDD_MODE = 1
*/
#define TAS2764_CONV_VBAT_PVDD_MODE BIT(1 )
static const struct reg_sequence tas2764_conv_vbat_pvdd_mode_seq[] = {
REG_SEQ0(TAS2764_REG(0 x0, 0 x6b), 0 x41)
};
/*
* Reset of DAC modulator when DSP is OFF
*/
#define TAS2764_DMOD_RST BIT(2 )
static const struct reg_sequence tas2764_dmod_rst_seq[] = {
REG_SEQ0(TAS2764_REG(0 x0, 0 x76), 0 x0)
};
/*
* Unknown 0 x133 / 0 x137 writes ( maybe TDM related )
*/
#define TAS2764_UNK_SEQ0 BIT(3 )
static const struct reg_sequence tas2764_unk_seq0[] = {
REG_SEQ0(TAS2764_REG(0 x1, 0 x33), 0 x80),
REG_SEQ0(TAS2764_REG(0 x1, 0 x37), 0 x3a),
};
/*
* Unknown 0 x614 - 0 x61f writes
*/
#define TAS2764_APPLE_UNK_SEQ1 BIT(4 )
static const struct reg_sequence tas2764_unk_seq1[] = {
REG_SEQ0(TAS2764_REG(0 x6, 0 x14), 0 x0),
REG_SEQ0(TAS2764_REG(0 x6, 0 x15), 0 x13),
REG_SEQ0(TAS2764_REG(0 x6, 0 x16), 0 x52),
REG_SEQ0(TAS2764_REG(0 x6, 0 x17), 0 x0),
REG_SEQ0(TAS2764_REG(0 x6, 0 x18), 0 xe4),
REG_SEQ0(TAS2764_REG(0 x6, 0 x19), 0 xc),
REG_SEQ0(TAS2764_REG(0 x6, 0 x16), 0 xaa),
REG_SEQ0(TAS2764_REG(0 x6, 0 x1b), 0 x0),
REG_SEQ0(TAS2764_REG(0 x6, 0 x1c), 0 x12),
REG_SEQ0(TAS2764_REG(0 x6, 0 x1d), 0 xa0),
REG_SEQ0(TAS2764_REG(0 x6, 0 x1e), 0 xd8),
REG_SEQ0(TAS2764_REG(0 x6, 0 x1f), 0 x0),
};
/*
* Unknown writes in the 0 xfd page ( with secondary paging inside )
*/
#define TAS2764_APPLE_UNK_SEQ2 BIT(5 )
static const struct reg_sequence tas2764_unk_seq2[] = {
REG_SEQ0(TAS2764_REG(0 xfd, 0 x0d), 0 xd),
REG_SEQ0(TAS2764_REG(0 xfd, 0 x6c), 0 x2),
REG_SEQ0(TAS2764_REG(0 xfd, 0 x6d), 0 xf),
REG_SEQ0(TAS2764_REG(0 xfd, 0 x0d), 0 x0),
};
/*
* Disable ' Thermal Threshold 1 '
*/
#define TAS2764_THERMAL_TH1_DISABLE BIT(6 )
static const struct reg_sequence tas2764_thermal_th1_dis_seq[] = {
REG_SEQ0(TAS2764_REG(0 x1, 0 x47), 0 x2),
};
/*
* Imitate Apple ' s shutdown dance
*/
#define TAS2764_SHUTDOWN_DANCE BIT(7 )
static const struct reg_sequence tas2764_shutdown_dance_init_seq[] = {
/*
* SDZ_MODE = 01 ( immediate )
*
* We want the shutdown to happen under the influence of
* the magic writes in the 0 xfdXX region , so make sure
* the shutdown is immediate and there ' s no grace period
* followed by the codec part .
*/
REG_SEQ0(TAS2764_REG(0 x0, 0 x7), 0 x60),
};
static const struct reg_sequence tas2764_pre_shutdown_seq[] = {
REG_SEQ0(TAS2764_REG(0 xfd, 0 x0d), 0 xd), /* switch hidden page */
REG_SEQ0(TAS2764_REG(0 xfd, 0 x64), 0 x4), /* do write (unknown semantics) */
REG_SEQ0(TAS2764_REG(0 xfd, 0 x0d), 0 x0), /* switch hidden page back */
};
static const struct reg_sequence tas2764_post_shutdown_seq[] = {
REG_SEQ0(TAS2764_REG(0 xfd, 0 x0d), 0 xd),
REG_SEQ0(TAS2764_REG(0 xfd, 0 x64), 0 x0), /* revert write from pre sequence */
REG_SEQ0(TAS2764_REG(0 xfd, 0 x0d), 0 x0),
};
static int tas2764_do_quirky_pwr_ctrl_change(struct tas2764_priv *tas2764,
unsigned int target)
{
unsigned int curr;
int ret;
curr = snd_soc_component_read_field(tas2764->component,
TAS2764_PWR_CTRL,
TAS2764_PWR_CTRL_MASK);
if (target == curr)
return 0 ;
/* Handle power state transition to shutdown */
if (target == TAS2764_PWR_CTRL_SHUTDOWN &&
(curr == TAS2764_PWR_CTRL_MUTE || curr == TAS2764_PWR_CTRL_ACTIVE)) {
ret = regmap_multi_reg_write(tas2764->regmap, tas2764_pre_shutdown_seq,
ARRAY_SIZE(tas2764_pre_shutdown_seq));
if (!ret)
ret = snd_soc_component_update_bits(tas2764->component,
TAS2764_PWR_CTRL,
TAS2764_PWR_CTRL_MASK,
TAS2764_PWR_CTRL_SHUTDOWN);
if (!ret)
ret = regmap_multi_reg_write(tas2764->regmap,
tas2764_post_shutdown_seq,
ARRAY_SIZE(tas2764_post_shutdown_seq));
}
ret = snd_soc_component_update_bits(tas2764->component, TAS2764_PWR_CTRL,
TAS2764_PWR_CTRL_MASK, target);
return ret;
}
/*
* Via devicetree ( TODO ) :
* - switch from spread spectrum to class - D switching
* - disable edge control
* - set BOP settings ( the BOP config bits * and * BOP_SRC )
*/
/*
* Other setup TODOs :
* - DVC ramp rate
*/
static const struct tas2764_quirk_init_sequence {
const struct reg_sequence *seq;
int len;
} tas2764_quirk_init_sequences[] = {
{ tas2764_noise_gate_dis_seq, ARRAY_SIZE(tas2764_noise_gate_dis_seq) },
{ tas2764_dmod_rst_seq, ARRAY_SIZE(tas2764_dmod_rst_seq) },
{ tas2764_conv_vbat_pvdd_mode_seq, ARRAY_SIZE(tas2764_conv_vbat_pvdd_mode_seq) },
{ tas2764_unk_seq0, ARRAY_SIZE(tas2764_unk_seq0) },
{ tas2764_unk_seq1, ARRAY_SIZE(tas2764_unk_seq1) },
{ tas2764_unk_seq2, ARRAY_SIZE(tas2764_unk_seq2) },
{ tas2764_thermal_th1_dis_seq, ARRAY_SIZE(tas2764_thermal_th1_dis_seq) },
{ tas2764_shutdown_dance_init_seq, ARRAY_SIZE(tas2764_shutdown_dance_init_seq) },
};
#endif /* __TAS2764_QUIRKS__ */
Messung V0.5 in Prozent C=96 H=93 G=94
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland