cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ssm2518.c (23077B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * SSM2518 amplifier audio driver
      4 *
      5 * Copyright 2013 Analog Devices Inc.
      6 *  Author: Lars-Peter Clausen <lars@metafoo.de>
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/init.h>
     11#include <linux/i2c.h>
     12#include <linux/regmap.h>
     13#include <linux/slab.h>
     14#include <linux/gpio.h>
     15#include <linux/of_gpio.h>
     16#include <linux/platform_data/ssm2518.h>
     17#include <sound/core.h>
     18#include <sound/pcm.h>
     19#include <sound/pcm_params.h>
     20#include <sound/soc.h>
     21#include <sound/initval.h>
     22#include <sound/tlv.h>
     23
     24#include "ssm2518.h"
     25
     26#define SSM2518_REG_POWER1		0x00
     27#define SSM2518_REG_CLOCK		0x01
     28#define SSM2518_REG_SAI_CTRL1		0x02
     29#define SSM2518_REG_SAI_CTRL2		0x03
     30#define SSM2518_REG_CHAN_MAP		0x04
     31#define SSM2518_REG_LEFT_VOL		0x05
     32#define SSM2518_REG_RIGHT_VOL		0x06
     33#define SSM2518_REG_MUTE_CTRL		0x07
     34#define SSM2518_REG_FAULT_CTRL		0x08
     35#define SSM2518_REG_POWER2		0x09
     36#define SSM2518_REG_DRC_1		0x0a
     37#define SSM2518_REG_DRC_2		0x0b
     38#define SSM2518_REG_DRC_3		0x0c
     39#define SSM2518_REG_DRC_4		0x0d
     40#define SSM2518_REG_DRC_5		0x0e
     41#define SSM2518_REG_DRC_6		0x0f
     42#define SSM2518_REG_DRC_7		0x10
     43#define SSM2518_REG_DRC_8		0x11
     44#define SSM2518_REG_DRC_9		0x12
     45
     46#define SSM2518_POWER1_RESET			BIT(7)
     47#define SSM2518_POWER1_NO_BCLK			BIT(5)
     48#define SSM2518_POWER1_MCS_MASK			(0xf << 1)
     49#define SSM2518_POWER1_MCS_64FS			(0x0 << 1)
     50#define SSM2518_POWER1_MCS_128FS		(0x1 << 1)
     51#define SSM2518_POWER1_MCS_256FS		(0x2 << 1)
     52#define SSM2518_POWER1_MCS_384FS		(0x3 << 1)
     53#define SSM2518_POWER1_MCS_512FS		(0x4 << 1)
     54#define SSM2518_POWER1_MCS_768FS		(0x5 << 1)
     55#define SSM2518_POWER1_MCS_100FS		(0x6 << 1)
     56#define SSM2518_POWER1_MCS_200FS		(0x7 << 1)
     57#define SSM2518_POWER1_MCS_400FS		(0x8 << 1)
     58#define SSM2518_POWER1_SPWDN			BIT(0)
     59
     60#define SSM2518_CLOCK_ASR			BIT(0)
     61
     62#define SSM2518_SAI_CTRL1_FMT_MASK		(0x3 << 5)
     63#define SSM2518_SAI_CTRL1_FMT_I2S		(0x0 << 5)
     64#define SSM2518_SAI_CTRL1_FMT_LJ		(0x1 << 5)
     65#define SSM2518_SAI_CTRL1_FMT_RJ_24BIT		(0x2 << 5)
     66#define SSM2518_SAI_CTRL1_FMT_RJ_16BIT		(0x3 << 5)
     67
     68#define SSM2518_SAI_CTRL1_SAI_MASK		(0x7 << 2)
     69#define SSM2518_SAI_CTRL1_SAI_I2S		(0x0 << 2)
     70#define SSM2518_SAI_CTRL1_SAI_TDM_2		(0x1 << 2)
     71#define SSM2518_SAI_CTRL1_SAI_TDM_4		(0x2 << 2)
     72#define SSM2518_SAI_CTRL1_SAI_TDM_8		(0x3 << 2)
     73#define SSM2518_SAI_CTRL1_SAI_TDM_16		(0x4 << 2)
     74#define SSM2518_SAI_CTRL1_SAI_MONO		(0x5 << 2)
     75
     76#define SSM2518_SAI_CTRL1_FS_MASK		(0x3)
     77#define SSM2518_SAI_CTRL1_FS_8000_12000		(0x0)
     78#define SSM2518_SAI_CTRL1_FS_16000_24000	(0x1)
     79#define SSM2518_SAI_CTRL1_FS_32000_48000	(0x2)
     80#define SSM2518_SAI_CTRL1_FS_64000_96000	(0x3)
     81
     82#define SSM2518_SAI_CTRL2_BCLK_INTERAL		BIT(7)
     83#define SSM2518_SAI_CTRL2_LRCLK_PULSE		BIT(6)
     84#define SSM2518_SAI_CTRL2_LRCLK_INVERT		BIT(5)
     85#define SSM2518_SAI_CTRL2_MSB			BIT(4)
     86#define SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK	(0x3 << 2)
     87#define SSM2518_SAI_CTRL2_SLOT_WIDTH_32		(0x0 << 2)
     88#define SSM2518_SAI_CTRL2_SLOT_WIDTH_24		(0x1 << 2)
     89#define SSM2518_SAI_CTRL2_SLOT_WIDTH_16		(0x2 << 2)
     90#define SSM2518_SAI_CTRL2_BCLK_INVERT		BIT(1)
     91
     92#define SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET	4
     93#define SSM2518_CHAN_MAP_RIGHT_SLOT_MASK	0xf0
     94#define SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET	0
     95#define SSM2518_CHAN_MAP_LEFT_SLOT_MASK		0x0f
     96
     97#define SSM2518_MUTE_CTRL_ANA_GAIN		BIT(5)
     98#define SSM2518_MUTE_CTRL_MUTE_MASTER		BIT(0)
     99
    100#define SSM2518_POWER2_APWDN			BIT(0)
    101
    102#define SSM2518_DAC_MUTE			BIT(6)
    103#define SSM2518_DAC_FS_MASK			0x07
    104#define SSM2518_DAC_FS_8000			0x00
    105#define SSM2518_DAC_FS_16000			0x01
    106#define SSM2518_DAC_FS_32000			0x02
    107#define SSM2518_DAC_FS_64000			0x03
    108#define SSM2518_DAC_FS_128000			0x04
    109
    110struct ssm2518 {
    111	struct regmap *regmap;
    112	bool right_j;
    113
    114	unsigned int sysclk;
    115	const struct snd_pcm_hw_constraint_list *constraints;
    116
    117	int enable_gpio;
    118};
    119
    120static const struct reg_default ssm2518_reg_defaults[] = {
    121	{ 0x00, 0x05 },
    122	{ 0x01, 0x00 },
    123	{ 0x02, 0x02 },
    124	{ 0x03, 0x00 },
    125	{ 0x04, 0x10 },
    126	{ 0x05, 0x40 },
    127	{ 0x06, 0x40 },
    128	{ 0x07, 0x81 },
    129	{ 0x08, 0x0c },
    130	{ 0x09, 0x99 },
    131	{ 0x0a, 0x7c },
    132	{ 0x0b, 0x5b },
    133	{ 0x0c, 0x57 },
    134	{ 0x0d, 0x89 },
    135	{ 0x0e, 0x8c },
    136	{ 0x0f, 0x77 },
    137	{ 0x10, 0x26 },
    138	{ 0x11, 0x1c },
    139	{ 0x12, 0x97 },
    140};
    141
    142static const DECLARE_TLV_DB_MINMAX_MUTE(ssm2518_vol_tlv, -7125, 2400);
    143static const DECLARE_TLV_DB_SCALE(ssm2518_compressor_tlv, -3400, 200, 0);
    144static const DECLARE_TLV_DB_SCALE(ssm2518_expander_tlv, -8100, 300, 0);
    145static const DECLARE_TLV_DB_SCALE(ssm2518_noise_gate_tlv, -9600, 300, 0);
    146static const DECLARE_TLV_DB_SCALE(ssm2518_post_drc_tlv, -2400, 300, 0);
    147
    148static const DECLARE_TLV_DB_RANGE(ssm2518_limiter_tlv,
    149	0, 7, TLV_DB_SCALE_ITEM(-2200, 200, 0),
    150	7, 15, TLV_DB_SCALE_ITEM(-800, 100, 0),
    151);
    152
    153static const char * const ssm2518_drc_peak_detector_attack_time_text[] = {
    154	"0 ms", "0.1 ms", "0.19 ms", "0.37 ms", "0.75 ms", "1.5 ms", "3 ms",
    155	"6 ms", "12 ms", "24 ms", "48 ms", "96 ms", "192 ms", "384 ms",
    156	"768 ms", "1536 ms",
    157};
    158
    159static const char * const ssm2518_drc_peak_detector_release_time_text[] = {
    160	"0 ms", "1.5 ms", "3 ms", "6 ms", "12 ms", "24 ms", "48 ms", "96 ms",
    161	"192 ms", "384 ms", "768 ms", "1536 ms", "3072 ms", "6144 ms",
    162	"12288 ms", "24576 ms"
    163};
    164
    165static const char * const ssm2518_drc_hold_time_text[] = {
    166	"0 ms", "0.67 ms", "1.33 ms", "2.67 ms", "5.33 ms", "10.66 ms",
    167	"21.32 ms", "42.64 ms", "85.28 ms", "170.56 ms", "341.12 ms",
    168	"682.24 ms", "1364 ms",
    169};
    170
    171static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
    172	SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
    173static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
    174	SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
    175static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
    176	SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
    177static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
    178	SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
    179static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
    180	SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
    181static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
    182	SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
    183static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
    184	SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
    185
    186static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
    187	SOC_SINGLE("Playback De-emphasis Switch", SSM2518_REG_MUTE_CTRL,
    188			4, 1, 0),
    189	SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2518_REG_LEFT_VOL,
    190			SSM2518_REG_RIGHT_VOL, 0, 0xff, 1, ssm2518_vol_tlv),
    191	SOC_DOUBLE("Master Playback Switch", SSM2518_REG_MUTE_CTRL, 2, 1, 1, 1),
    192
    193	SOC_SINGLE("Amp Low Power Mode Switch", SSM2518_REG_POWER2, 4, 1, 0),
    194	SOC_SINGLE("DAC Low Power Mode Switch", SSM2518_REG_POWER2, 3, 1, 0),
    195
    196	SOC_SINGLE("DRC Limiter Switch", SSM2518_REG_DRC_1, 5, 1, 0),
    197	SOC_SINGLE("DRC Compressor Switch", SSM2518_REG_DRC_1, 4, 1, 0),
    198	SOC_SINGLE("DRC Expander Switch", SSM2518_REG_DRC_1, 3, 1, 0),
    199	SOC_SINGLE("DRC Noise Gate Switch", SSM2518_REG_DRC_1, 2, 1, 0),
    200	SOC_DOUBLE("DRC Switch", SSM2518_REG_DRC_1, 0, 1, 1, 0),
    201
    202	SOC_SINGLE_TLV("DRC Limiter Threshold Volume",
    203			SSM2518_REG_DRC_3, 4, 15, 1, ssm2518_limiter_tlv),
    204	SOC_SINGLE_TLV("DRC Compressor Lower Threshold Volume",
    205			SSM2518_REG_DRC_3, 0, 15, 1, ssm2518_compressor_tlv),
    206	SOC_SINGLE_TLV("DRC Expander Upper Threshold Volume", SSM2518_REG_DRC_4,
    207			4, 15, 1, ssm2518_expander_tlv),
    208	SOC_SINGLE_TLV("DRC Noise Gate Threshold Volume",
    209			SSM2518_REG_DRC_4, 0, 15, 1, ssm2518_noise_gate_tlv),
    210	SOC_SINGLE_TLV("DRC Upper Output Threshold Volume",
    211			SSM2518_REG_DRC_5, 4, 15, 1, ssm2518_limiter_tlv),
    212	SOC_SINGLE_TLV("DRC Lower Output Threshold Volume",
    213			SSM2518_REG_DRC_5, 0, 15, 1, ssm2518_noise_gate_tlv),
    214	SOC_SINGLE_TLV("DRC Post Volume", SSM2518_REG_DRC_8,
    215			2, 15, 1, ssm2518_post_drc_tlv),
    216
    217	SOC_ENUM("DRC Peak Detector Attack Time",
    218		ssm2518_drc_peak_detector_attack_time_enum),
    219	SOC_ENUM("DRC Peak Detector Release Time",
    220		ssm2518_drc_peak_detector_release_time_enum),
    221	SOC_ENUM("DRC Attack Time", ssm2518_drc_attack_time_enum),
    222	SOC_ENUM("DRC Decay Time", ssm2518_drc_decay_time_enum),
    223	SOC_ENUM("DRC Hold Time", ssm2518_drc_hold_time_enum),
    224	SOC_ENUM("DRC Noise Gate Hold Time",
    225		ssm2518_drc_noise_gate_hold_time_enum),
    226	SOC_ENUM("DRC RMS Averaging Time", ssm2518_drc_rms_averaging_time_enum),
    227};
    228
    229static const struct snd_soc_dapm_widget ssm2518_dapm_widgets[] = {
    230	SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SSM2518_REG_POWER2, 1, 1),
    231	SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SSM2518_REG_POWER2, 2, 1),
    232
    233	SND_SOC_DAPM_OUTPUT("OUTL"),
    234	SND_SOC_DAPM_OUTPUT("OUTR"),
    235};
    236
    237static const struct snd_soc_dapm_route ssm2518_routes[] = {
    238	{ "OUTL", NULL, "DACL" },
    239	{ "OUTR", NULL, "DACR" },
    240};
    241
    242struct ssm2518_mcs_lut {
    243	unsigned int rate;
    244	const unsigned int *sysclks;
    245};
    246
    247static const unsigned int ssm2518_sysclks_2048000[] = {
    248	2048000, 4096000, 8192000, 12288000, 16384000, 24576000,
    249	3200000, 6400000, 12800000, 0
    250};
    251
    252static const unsigned int ssm2518_sysclks_2822000[] = {
    253	2822000, 5644800, 11289600, 16934400, 22579200, 33868800,
    254	4410000, 8820000, 17640000, 0
    255};
    256
    257static const unsigned int ssm2518_sysclks_3072000[] = {
    258	3072000, 6144000, 12288000, 16384000, 24576000, 38864000,
    259	4800000, 9600000, 19200000, 0
    260};
    261
    262static const struct ssm2518_mcs_lut ssm2518_mcs_lut[] = {
    263	{ 8000,  ssm2518_sysclks_2048000, },
    264	{ 11025, ssm2518_sysclks_2822000, },
    265	{ 12000, ssm2518_sysclks_3072000, },
    266	{ 16000, ssm2518_sysclks_2048000, },
    267	{ 24000, ssm2518_sysclks_3072000, },
    268	{ 22050, ssm2518_sysclks_2822000, },
    269	{ 32000, ssm2518_sysclks_2048000, },
    270	{ 44100, ssm2518_sysclks_2822000, },
    271	{ 48000, ssm2518_sysclks_3072000, },
    272	{ 96000, ssm2518_sysclks_3072000, },
    273};
    274
    275static const unsigned int ssm2518_rates_2048000[] = {
    276	8000, 16000, 32000,
    277};
    278
    279static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2048000 = {
    280	.list = ssm2518_rates_2048000,
    281	.count = ARRAY_SIZE(ssm2518_rates_2048000),
    282};
    283
    284static const unsigned int ssm2518_rates_2822000[] = {
    285	11025, 22050, 44100,
    286};
    287
    288static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2822000 = {
    289	.list = ssm2518_rates_2822000,
    290	.count = ARRAY_SIZE(ssm2518_rates_2822000),
    291};
    292
    293static const unsigned int ssm2518_rates_3072000[] = {
    294	12000, 24000, 48000, 96000,
    295};
    296
    297static const struct snd_pcm_hw_constraint_list ssm2518_constraints_3072000 = {
    298	.list = ssm2518_rates_3072000,
    299	.count = ARRAY_SIZE(ssm2518_rates_3072000),
    300};
    301
    302static const unsigned int ssm2518_rates_12288000[] = {
    303	8000, 12000, 16000, 24000, 32000, 48000, 96000,
    304};
    305
    306static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
    307	.list = ssm2518_rates_12288000,
    308	.count = ARRAY_SIZE(ssm2518_rates_12288000),
    309};
    310
    311static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
    312	unsigned int rate)
    313{
    314	const unsigned int *sysclks = NULL;
    315	int i;
    316
    317	for (i = 0; i < ARRAY_SIZE(ssm2518_mcs_lut); i++) {
    318		if (ssm2518_mcs_lut[i].rate == rate) {
    319			sysclks = ssm2518_mcs_lut[i].sysclks;
    320			break;
    321		}
    322	}
    323
    324	if (!sysclks)
    325		return -EINVAL;
    326
    327	for (i = 0; sysclks[i]; i++) {
    328		if (sysclks[i] == ssm2518->sysclk)
    329			return i;
    330	}
    331
    332	return -EINVAL;
    333}
    334
    335static int ssm2518_hw_params(struct snd_pcm_substream *substream,
    336	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
    337{
    338	struct snd_soc_component *component = dai->component;
    339	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
    340	unsigned int rate = params_rate(params);
    341	unsigned int ctrl1, ctrl1_mask;
    342	int mcs;
    343	int ret;
    344
    345	mcs = ssm2518_lookup_mcs(ssm2518, rate);
    346	if (mcs < 0)
    347		return mcs;
    348
    349	ctrl1_mask = SSM2518_SAI_CTRL1_FS_MASK;
    350
    351	if (rate >= 8000 && rate <= 12000)
    352		ctrl1 = SSM2518_SAI_CTRL1_FS_8000_12000;
    353	else if (rate >= 16000 && rate <= 24000)
    354		ctrl1 = SSM2518_SAI_CTRL1_FS_16000_24000;
    355	else if (rate >= 32000 && rate <= 48000)
    356		ctrl1 = SSM2518_SAI_CTRL1_FS_32000_48000;
    357	else if (rate >= 64000 && rate <= 96000)
    358		ctrl1 = SSM2518_SAI_CTRL1_FS_64000_96000;
    359	else
    360		return -EINVAL;
    361
    362	if (ssm2518->right_j) {
    363		switch (params_width(params)) {
    364		case 16:
    365			ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_16BIT;
    366			break;
    367		case 24:
    368			ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
    369			break;
    370		default:
    371			return -EINVAL;
    372		}
    373		ctrl1_mask |= SSM2518_SAI_CTRL1_FMT_MASK;
    374	}
    375
    376	/* Disable auto samplerate detection */
    377	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_CLOCK,
    378				SSM2518_CLOCK_ASR, SSM2518_CLOCK_ASR);
    379	if (ret < 0)
    380		return ret;
    381
    382	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
    383				ctrl1_mask, ctrl1);
    384	if (ret < 0)
    385		return ret;
    386
    387	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
    388				SSM2518_POWER1_MCS_MASK, mcs << 1);
    389}
    390
    391static int ssm2518_mute(struct snd_soc_dai *dai, int mute, int direction)
    392{
    393	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
    394	unsigned int val;
    395
    396	if (mute)
    397		val = SSM2518_MUTE_CTRL_MUTE_MASTER;
    398	else
    399		val = 0;
    400
    401	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_MUTE_CTRL,
    402			SSM2518_MUTE_CTRL_MUTE_MASTER, val);
    403}
    404
    405static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
    406{
    407	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
    408	unsigned int ctrl1 = 0, ctrl2 = 0;
    409	bool invert_fclk;
    410	int ret;
    411
    412	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    413	case SND_SOC_DAIFMT_CBS_CFS:
    414		break;
    415	default:
    416		return -EINVAL;
    417	}
    418
    419	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    420	case SND_SOC_DAIFMT_NB_NF:
    421		invert_fclk = false;
    422		break;
    423	case SND_SOC_DAIFMT_IB_NF:
    424		ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
    425		invert_fclk = false;
    426		break;
    427	case SND_SOC_DAIFMT_NB_IF:
    428		invert_fclk = true;
    429		break;
    430	case SND_SOC_DAIFMT_IB_IF:
    431		ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
    432		invert_fclk = true;
    433		break;
    434	default:
    435		return -EINVAL;
    436	}
    437
    438	ssm2518->right_j = false;
    439	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    440	case SND_SOC_DAIFMT_I2S:
    441		ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
    442		break;
    443	case SND_SOC_DAIFMT_LEFT_J:
    444		ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
    445		invert_fclk = !invert_fclk;
    446		break;
    447	case SND_SOC_DAIFMT_RIGHT_J:
    448		ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
    449		ssm2518->right_j = true;
    450		invert_fclk = !invert_fclk;
    451		break;
    452	case SND_SOC_DAIFMT_DSP_A:
    453		ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
    454		ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
    455		invert_fclk = false;
    456		break;
    457	case SND_SOC_DAIFMT_DSP_B:
    458		ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
    459		ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
    460		invert_fclk = false;
    461		break;
    462	default:
    463		return -EINVAL;
    464	}
    465
    466	if (invert_fclk)
    467		ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_INVERT;
    468
    469	ret = regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL1, ctrl1);
    470	if (ret)
    471		return ret;
    472
    473	return regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL2, ctrl2);
    474}
    475
    476static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
    477{
    478	int ret = 0;
    479
    480	if (!enable) {
    481		ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
    482			SSM2518_POWER1_SPWDN, SSM2518_POWER1_SPWDN);
    483		regcache_mark_dirty(ssm2518->regmap);
    484	}
    485
    486	if (gpio_is_valid(ssm2518->enable_gpio))
    487		gpio_set_value(ssm2518->enable_gpio, enable);
    488
    489	regcache_cache_only(ssm2518->regmap, !enable);
    490
    491	if (enable) {
    492		ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
    493			SSM2518_POWER1_SPWDN | SSM2518_POWER1_RESET, 0x00);
    494		regcache_sync(ssm2518->regmap);
    495	}
    496
    497	return ret;
    498}
    499
    500static int ssm2518_set_bias_level(struct snd_soc_component *component,
    501	enum snd_soc_bias_level level)
    502{
    503	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
    504	int ret = 0;
    505
    506	switch (level) {
    507	case SND_SOC_BIAS_ON:
    508		break;
    509	case SND_SOC_BIAS_PREPARE:
    510		break;
    511	case SND_SOC_BIAS_STANDBY:
    512		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
    513			ret = ssm2518_set_power(ssm2518, true);
    514		break;
    515	case SND_SOC_BIAS_OFF:
    516		ret = ssm2518_set_power(ssm2518, false);
    517		break;
    518	}
    519
    520	return ret;
    521}
    522
    523static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
    524	unsigned int rx_mask, int slots, int width)
    525{
    526	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
    527	unsigned int ctrl1, ctrl2;
    528	int left_slot, right_slot;
    529	int ret;
    530
    531	if (slots == 0)
    532		return regmap_update_bits(ssm2518->regmap,
    533			SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
    534			SSM2518_SAI_CTRL1_SAI_I2S);
    535
    536	if (tx_mask == 0 || rx_mask != 0)
    537		return -EINVAL;
    538
    539	if (slots == 1) {
    540		if (tx_mask != 1)
    541			return -EINVAL;
    542		left_slot = 0;
    543		right_slot = 0;
    544	} else {
    545		/* We assume the left channel < right channel */
    546		left_slot = __ffs(tx_mask);
    547		tx_mask &= ~(1 << left_slot);
    548		if (tx_mask == 0) {
    549			right_slot = left_slot;
    550		} else {
    551			right_slot = __ffs(tx_mask);
    552			tx_mask &= ~(1 << right_slot);
    553		}
    554	}
    555
    556	if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
    557		return -EINVAL;
    558
    559	switch (width) {
    560	case 16:
    561		ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
    562		break;
    563	case 24:
    564		ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
    565		break;
    566	case 32:
    567		ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
    568		break;
    569	default:
    570		return -EINVAL;
    571	}
    572
    573	switch (slots) {
    574	case 1:
    575		ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
    576		break;
    577	case 2:
    578		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
    579		break;
    580	case 4:
    581		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
    582		break;
    583	case 8:
    584		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
    585		break;
    586	case 16:
    587		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
    588		break;
    589	default:
    590		return -EINVAL;
    591	}
    592
    593	ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
    594		(left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
    595		(right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
    596	if (ret)
    597		return ret;
    598
    599	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
    600		SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
    601	if (ret)
    602		return ret;
    603
    604	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
    605		SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
    606}
    607
    608static int ssm2518_startup(struct snd_pcm_substream *substream,
    609	struct snd_soc_dai *dai)
    610{
    611	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
    612
    613	if (ssm2518->constraints)
    614		snd_pcm_hw_constraint_list(substream->runtime, 0,
    615				SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
    616
    617	return 0;
    618}
    619
    620#define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
    621			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
    622
    623static const struct snd_soc_dai_ops ssm2518_dai_ops = {
    624	.startup = ssm2518_startup,
    625	.hw_params	= ssm2518_hw_params,
    626	.mute_stream	= ssm2518_mute,
    627	.set_fmt	= ssm2518_set_dai_fmt,
    628	.set_tdm_slot	= ssm2518_set_tdm_slot,
    629	.no_capture_mute = 1,
    630};
    631
    632static struct snd_soc_dai_driver ssm2518_dai = {
    633	.name = "ssm2518-hifi",
    634	.playback = {
    635		.stream_name = "Playback",
    636		.channels_min = 2,
    637		.channels_max = 2,
    638		.rates = SNDRV_PCM_RATE_8000_96000,
    639		.formats = SSM2518_FORMATS,
    640	},
    641	.ops = &ssm2518_dai_ops,
    642};
    643
    644static int ssm2518_set_sysclk(struct snd_soc_component *component, int clk_id,
    645	int source, unsigned int freq, int dir)
    646{
    647	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
    648	unsigned int val;
    649
    650	if (clk_id != SSM2518_SYSCLK)
    651		return -EINVAL;
    652
    653	switch (source) {
    654	case SSM2518_SYSCLK_SRC_MCLK:
    655		val = 0;
    656		break;
    657	case SSM2518_SYSCLK_SRC_BCLK:
    658		/* In this case the bitclock is used as the system clock, and
    659		 * the bitclock signal needs to be connected to the MCLK pin and
    660		 * the BCLK pin is left unconnected */
    661		val = SSM2518_POWER1_NO_BCLK;
    662		break;
    663	default:
    664		return -EINVAL;
    665	}
    666
    667	switch (freq) {
    668	case 0:
    669		ssm2518->constraints = NULL;
    670		break;
    671	case 2048000:
    672	case 4096000:
    673	case 8192000:
    674	case 3200000:
    675	case 6400000:
    676	case 12800000:
    677		ssm2518->constraints = &ssm2518_constraints_2048000;
    678		break;
    679	case 2822000:
    680	case 5644800:
    681	case 11289600:
    682	case 16934400:
    683	case 22579200:
    684	case 33868800:
    685	case 4410000:
    686	case 8820000:
    687	case 17640000:
    688		ssm2518->constraints = &ssm2518_constraints_2822000;
    689		break;
    690	case 3072000:
    691	case 6144000:
    692	case 38864000:
    693	case 4800000:
    694	case 9600000:
    695	case 19200000:
    696		ssm2518->constraints = &ssm2518_constraints_3072000;
    697		break;
    698	case 12288000:
    699	case 16384000:
    700	case 24576000:
    701		ssm2518->constraints = &ssm2518_constraints_12288000;
    702		break;
    703	default:
    704		return -EINVAL;
    705	}
    706
    707	ssm2518->sysclk = freq;
    708
    709	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
    710			SSM2518_POWER1_NO_BCLK, val);
    711}
    712
    713static const struct snd_soc_component_driver ssm2518_component_driver = {
    714	.set_bias_level		= ssm2518_set_bias_level,
    715	.set_sysclk		= ssm2518_set_sysclk,
    716	.controls		= ssm2518_snd_controls,
    717	.num_controls		= ARRAY_SIZE(ssm2518_snd_controls),
    718	.dapm_widgets		= ssm2518_dapm_widgets,
    719	.num_dapm_widgets	= ARRAY_SIZE(ssm2518_dapm_widgets),
    720	.dapm_routes		= ssm2518_routes,
    721	.num_dapm_routes	= ARRAY_SIZE(ssm2518_routes),
    722	.use_pmdown_time	= 1,
    723	.endianness		= 1,
    724	.non_legacy_dai_naming	= 1,
    725};
    726
    727static const struct regmap_config ssm2518_regmap_config = {
    728	.val_bits = 8,
    729	.reg_bits = 8,
    730
    731	.max_register = SSM2518_REG_DRC_9,
    732
    733	.cache_type = REGCACHE_RBTREE,
    734	.reg_defaults = ssm2518_reg_defaults,
    735	.num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
    736};
    737
    738static int ssm2518_i2c_probe(struct i2c_client *i2c)
    739{
    740	struct ssm2518_platform_data *pdata = i2c->dev.platform_data;
    741	struct ssm2518 *ssm2518;
    742	int ret;
    743
    744	ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
    745	if (ssm2518 == NULL)
    746		return -ENOMEM;
    747
    748	if (pdata) {
    749		ssm2518->enable_gpio = pdata->enable_gpio;
    750	} else if (i2c->dev.of_node) {
    751		ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0);
    752		if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT)
    753			return ssm2518->enable_gpio;
    754	} else {
    755		ssm2518->enable_gpio = -1;
    756	}
    757
    758	if (gpio_is_valid(ssm2518->enable_gpio)) {
    759		ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio,
    760				GPIOF_OUT_INIT_HIGH, "SSM2518 nSD");
    761		if (ret)
    762			return ret;
    763	}
    764
    765	i2c_set_clientdata(i2c, ssm2518);
    766
    767	ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
    768	if (IS_ERR(ssm2518->regmap))
    769		return PTR_ERR(ssm2518->regmap);
    770
    771	/*
    772	 * The reset bit is obviously volatile, but we need to be able to cache
    773	 * the other bits in the register, so we can't just mark the whole
    774	 * register as volatile. Since this is the only place where we'll ever
    775	 * touch the reset bit just bypass the cache for this operation.
    776	 */
    777	regcache_cache_bypass(ssm2518->regmap, true);
    778	ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
    779			SSM2518_POWER1_RESET);
    780	regcache_cache_bypass(ssm2518->regmap, false);
    781	if (ret)
    782		return ret;
    783
    784	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
    785				SSM2518_POWER2_APWDN, 0x00);
    786	if (ret)
    787		return ret;
    788
    789	ret = ssm2518_set_power(ssm2518, false);
    790	if (ret)
    791		return ret;
    792
    793	return devm_snd_soc_register_component(&i2c->dev,
    794			&ssm2518_component_driver,
    795			&ssm2518_dai, 1);
    796}
    797
    798#ifdef CONFIG_OF
    799static const struct of_device_id ssm2518_dt_ids[] = {
    800	{ .compatible = "adi,ssm2518", },
    801	{ }
    802};
    803MODULE_DEVICE_TABLE(of, ssm2518_dt_ids);
    804#endif
    805
    806static const struct i2c_device_id ssm2518_i2c_ids[] = {
    807	{ "ssm2518", 0 },
    808	{ }
    809};
    810MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
    811
    812static struct i2c_driver ssm2518_driver = {
    813	.driver = {
    814		.name = "ssm2518",
    815		.of_match_table = of_match_ptr(ssm2518_dt_ids),
    816	},
    817	.probe_new = ssm2518_i2c_probe,
    818	.id_table = ssm2518_i2c_ids,
    819};
    820module_i2c_driver(ssm2518_driver);
    821
    822MODULE_DESCRIPTION("ASoC SSM2518 driver");
    823MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
    824MODULE_LICENSE("GPL");