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

ad1836.c (10749B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2 /*
      3 * Audio Codec driver supporting:
      4 *  AD1835A, AD1836, AD1837A, AD1838A, AD1839A
      5 *
      6 * Copyright 2009-2011 Analog Devices Inc.
      7 */
      8
      9#include <linux/init.h>
     10#include <linux/slab.h>
     11#include <linux/module.h>
     12#include <linux/kernel.h>
     13#include <linux/device.h>
     14#include <sound/core.h>
     15#include <sound/pcm.h>
     16#include <sound/pcm_params.h>
     17#include <sound/initval.h>
     18#include <sound/soc.h>
     19#include <sound/tlv.h>
     20#include <linux/spi/spi.h>
     21#include <linux/regmap.h>
     22
     23#include "ad1836.h"
     24
     25enum ad1836_type {
     26	AD1835,
     27	AD1836,
     28	AD1838,
     29};
     30
     31/* codec private data */
     32struct ad1836_priv {
     33	enum ad1836_type type;
     34	struct regmap *regmap;
     35};
     36
     37/*
     38 * AD1836 volume/mute/de-emphasis etc. controls
     39 */
     40static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
     41
     42static SOC_ENUM_SINGLE_DECL(ad1836_deemp_enum,
     43			    AD1836_DAC_CTRL1, 8, ad1836_deemp);
     44
     45#define AD1836_DAC_VOLUME(x) \
     46	SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \
     47			AD1836_DAC_R_VOL(x), 0, 0x3FF, 0)
     48
     49#define AD1836_DAC_SWITCH(x) \
     50	SOC_DOUBLE("DAC" #x " Playback Switch", AD1836_DAC_CTRL2, \
     51			AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
     52
     53#define AD1836_ADC_SWITCH(x) \
     54	SOC_DOUBLE("ADC" #x " Capture Switch", AD1836_ADC_CTRL2, \
     55		AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
     56
     57static const struct snd_kcontrol_new ad183x_dac_controls[] = {
     58	AD1836_DAC_VOLUME(1),
     59	AD1836_DAC_SWITCH(1),
     60	AD1836_DAC_VOLUME(2),
     61	AD1836_DAC_SWITCH(2),
     62	AD1836_DAC_VOLUME(3),
     63	AD1836_DAC_SWITCH(3),
     64	AD1836_DAC_VOLUME(4),
     65	AD1836_DAC_SWITCH(4),
     66};
     67
     68static const struct snd_soc_dapm_widget ad183x_dac_dapm_widgets[] = {
     69	SND_SOC_DAPM_OUTPUT("DAC1OUT"),
     70	SND_SOC_DAPM_OUTPUT("DAC2OUT"),
     71	SND_SOC_DAPM_OUTPUT("DAC3OUT"),
     72	SND_SOC_DAPM_OUTPUT("DAC4OUT"),
     73};
     74
     75static const struct snd_soc_dapm_route ad183x_dac_routes[] = {
     76	{ "DAC1OUT", NULL, "DAC" },
     77	{ "DAC2OUT", NULL, "DAC" },
     78	{ "DAC3OUT", NULL, "DAC" },
     79	{ "DAC4OUT", NULL, "DAC" },
     80};
     81
     82static const struct snd_kcontrol_new ad183x_adc_controls[] = {
     83	AD1836_ADC_SWITCH(1),
     84	AD1836_ADC_SWITCH(2),
     85	AD1836_ADC_SWITCH(3),
     86};
     87
     88static const struct snd_soc_dapm_widget ad183x_adc_dapm_widgets[] = {
     89	SND_SOC_DAPM_INPUT("ADC1IN"),
     90	SND_SOC_DAPM_INPUT("ADC2IN"),
     91};
     92
     93static const struct snd_soc_dapm_route ad183x_adc_routes[] = {
     94	{ "ADC", NULL, "ADC1IN" },
     95	{ "ADC", NULL, "ADC2IN" },
     96};
     97
     98static const struct snd_kcontrol_new ad183x_controls[] = {
     99	/* ADC high-pass filter */
    100	SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
    101			AD1836_ADC_HIGHPASS_FILTER, 1, 0),
    102
    103	/* DAC de-emphasis */
    104	SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
    105};
    106
    107static const struct snd_soc_dapm_widget ad183x_dapm_widgets[] = {
    108	SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
    109				AD1836_DAC_POWERDOWN, 1),
    110	SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
    111	SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
    112				AD1836_ADC_POWERDOWN, 1, NULL, 0),
    113};
    114
    115static const struct snd_soc_dapm_route ad183x_dapm_routes[] = {
    116	{ "DAC", NULL, "ADC_PWR" },
    117	{ "ADC", NULL, "ADC_PWR" },
    118};
    119
    120static const DECLARE_TLV_DB_SCALE(ad1836_in_tlv, 0, 300, 0);
    121
    122static const struct snd_kcontrol_new ad1836_controls[] = {
    123	SOC_DOUBLE_TLV("ADC2 Capture Volume", AD1836_ADC_CTRL1, 3, 0, 4, 0,
    124	    ad1836_in_tlv),
    125};
    126
    127/*
    128 * DAI ops entries
    129 */
    130
    131static int ad1836_set_dai_fmt(struct snd_soc_dai *codec_dai,
    132		unsigned int fmt)
    133{
    134	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    135	/* at present, we support adc aux mode to interface with
    136	 * blackfin sport tdm mode
    137	 */
    138	case SND_SOC_DAIFMT_DSP_A:
    139		break;
    140	default:
    141		return -EINVAL;
    142	}
    143
    144	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    145	case SND_SOC_DAIFMT_IB_IF:
    146		break;
    147	default:
    148		return -EINVAL;
    149	}
    150
    151	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
    152	/* ALCLK,ABCLK are both output, AD1836 can only be provider */
    153	case SND_SOC_DAIFMT_CBP_CFP:
    154		break;
    155	default:
    156		return -EINVAL;
    157	}
    158
    159	return 0;
    160}
    161
    162static int ad1836_hw_params(struct snd_pcm_substream *substream,
    163		struct snd_pcm_hw_params *params,
    164		struct snd_soc_dai *dai)
    165{
    166	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(dai->component);
    167	int word_len = 0;
    168
    169	/* bit size */
    170	switch (params_width(params)) {
    171	case 16:
    172		word_len = AD1836_WORD_LEN_16;
    173		break;
    174	case 20:
    175		word_len = AD1836_WORD_LEN_20;
    176		break;
    177	case 24:
    178	case 32:
    179		word_len = AD1836_WORD_LEN_24;
    180		break;
    181	default:
    182		return -EINVAL;
    183	}
    184
    185	regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1,
    186		AD1836_DAC_WORD_LEN_MASK,
    187		word_len << AD1836_DAC_WORD_LEN_OFFSET);
    188
    189	regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
    190		AD1836_ADC_WORD_LEN_MASK,
    191		word_len << AD1836_ADC_WORD_OFFSET);
    192
    193	return 0;
    194}
    195
    196static const struct snd_soc_dai_ops ad1836_dai_ops = {
    197	.hw_params = ad1836_hw_params,
    198	.set_fmt = ad1836_set_dai_fmt,
    199};
    200
    201#define AD183X_DAI(_name, num_dacs, num_adcs) \
    202{ \
    203	.name = _name "-hifi", \
    204	.playback = { \
    205		.stream_name = "Playback", \
    206		.channels_min = 2, \
    207		.channels_max = (num_dacs) * 2, \
    208		.rates = SNDRV_PCM_RATE_48000,  \
    209		.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
    210			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
    211	}, \
    212	.capture = { \
    213		.stream_name = "Capture", \
    214		.channels_min = 2, \
    215		.channels_max = (num_adcs) * 2, \
    216		.rates = SNDRV_PCM_RATE_48000, \
    217		.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
    218			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
    219	}, \
    220	.ops = &ad1836_dai_ops, \
    221}
    222
    223static struct snd_soc_dai_driver ad183x_dais[] = {
    224	[AD1835] = AD183X_DAI("ad1835", 4, 1),
    225	[AD1836] = AD183X_DAI("ad1836", 3, 2),
    226	[AD1838] = AD183X_DAI("ad1838", 3, 1),
    227};
    228
    229#ifdef CONFIG_PM
    230static int ad1836_suspend(struct snd_soc_component *component)
    231{
    232	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
    233	/* reset clock control mode */
    234	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
    235		AD1836_ADC_SERFMT_MASK, 0);
    236}
    237
    238static int ad1836_resume(struct snd_soc_component *component)
    239{
    240	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
    241	/* restore clock control mode */
    242	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
    243		AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
    244}
    245#else
    246#define ad1836_suspend NULL
    247#define ad1836_resume  NULL
    248#endif
    249
    250static int ad1836_probe(struct snd_soc_component *component)
    251{
    252	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
    253	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
    254	int num_dacs, num_adcs;
    255	int ret = 0;
    256	int i;
    257
    258	num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
    259	num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
    260
    261	/* default setting for ad1836 */
    262	/* de-emphasis: 48kHz, power-on dac */
    263	regmap_write(ad1836->regmap, AD1836_DAC_CTRL1, 0x300);
    264	/* unmute dac channels */
    265	regmap_write(ad1836->regmap, AD1836_DAC_CTRL2, 0x0);
    266	/* high-pass filter enable, power-on adc */
    267	regmap_write(ad1836->regmap, AD1836_ADC_CTRL1, 0x100);
    268	/* unmute adc channles, adc aux mode */
    269	regmap_write(ad1836->regmap, AD1836_ADC_CTRL2, 0x180);
    270	/* volume */
    271	for (i = 1; i <= num_dacs; ++i) {
    272		regmap_write(ad1836->regmap, AD1836_DAC_L_VOL(i), 0x3FF);
    273		regmap_write(ad1836->regmap, AD1836_DAC_R_VOL(i), 0x3FF);
    274	}
    275
    276	if (ad1836->type == AD1836) {
    277		/* left/right diff:PGA/MUX */
    278		regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A);
    279		ret = snd_soc_add_component_controls(component, ad1836_controls,
    280				ARRAY_SIZE(ad1836_controls));
    281		if (ret)
    282			return ret;
    283	} else {
    284		regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00);
    285	}
    286
    287	ret = snd_soc_add_component_controls(component, ad183x_dac_controls, num_dacs * 2);
    288	if (ret)
    289		return ret;
    290
    291	ret = snd_soc_add_component_controls(component, ad183x_adc_controls, num_adcs);
    292	if (ret)
    293		return ret;
    294
    295	ret = snd_soc_dapm_new_controls(dapm, ad183x_dac_dapm_widgets, num_dacs);
    296	if (ret)
    297		return ret;
    298
    299	ret = snd_soc_dapm_new_controls(dapm, ad183x_adc_dapm_widgets, num_adcs);
    300	if (ret)
    301		return ret;
    302
    303	ret = snd_soc_dapm_add_routes(dapm, ad183x_dac_routes, num_dacs);
    304	if (ret)
    305		return ret;
    306
    307	ret = snd_soc_dapm_add_routes(dapm, ad183x_adc_routes, num_adcs);
    308
    309	return ret;
    310}
    311
    312/* power down chip */
    313static void ad1836_remove(struct snd_soc_component *component)
    314{
    315	struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
    316	/* reset clock control mode */
    317	regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
    318		AD1836_ADC_SERFMT_MASK, 0);
    319}
    320
    321static const struct snd_soc_component_driver soc_component_dev_ad1836 = {
    322	.probe			= ad1836_probe,
    323	.remove			= ad1836_remove,
    324	.suspend		= ad1836_suspend,
    325	.resume			= ad1836_resume,
    326	.controls		= ad183x_controls,
    327	.num_controls		= ARRAY_SIZE(ad183x_controls),
    328	.dapm_widgets		= ad183x_dapm_widgets,
    329	.num_dapm_widgets	= ARRAY_SIZE(ad183x_dapm_widgets),
    330	.dapm_routes		= ad183x_dapm_routes,
    331	.num_dapm_routes	= ARRAY_SIZE(ad183x_dapm_routes),
    332	.idle_bias_on		= 1,
    333	.use_pmdown_time	= 1,
    334	.endianness		= 1,
    335	.non_legacy_dai_naming	= 1,
    336};
    337
    338static const struct reg_default ad1836_reg_defaults[] = {
    339	{ AD1836_DAC_CTRL1, 0x0000 },
    340	{ AD1836_DAC_CTRL2, 0x0000 },
    341	{ AD1836_DAC_L_VOL(0), 0x0000 },
    342	{ AD1836_DAC_R_VOL(0), 0x0000 },
    343	{ AD1836_DAC_L_VOL(1), 0x0000 },
    344	{ AD1836_DAC_R_VOL(1), 0x0000 },
    345	{ AD1836_DAC_L_VOL(2), 0x0000 },
    346	{ AD1836_DAC_R_VOL(2), 0x0000 },
    347	{ AD1836_DAC_L_VOL(3), 0x0000 },
    348	{ AD1836_DAC_R_VOL(3), 0x0000 },
    349	{ AD1836_ADC_CTRL1, 0x0000 },
    350	{ AD1836_ADC_CTRL2, 0x0000 },
    351	{ AD1836_ADC_CTRL3, 0x0000 },
    352};
    353
    354static const struct regmap_config ad1836_regmap_config = {
    355	.val_bits = 12,
    356	.reg_bits = 4,
    357	.read_flag_mask = 0x08,
    358
    359	.max_register = AD1836_ADC_CTRL3,
    360	.reg_defaults = ad1836_reg_defaults,
    361	.num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults),
    362	.cache_type = REGCACHE_RBTREE,
    363};
    364
    365static int ad1836_spi_probe(struct spi_device *spi)
    366{
    367	struct ad1836_priv *ad1836;
    368	int ret;
    369
    370	ad1836 = devm_kzalloc(&spi->dev, sizeof(struct ad1836_priv),
    371			      GFP_KERNEL);
    372	if (ad1836 == NULL)
    373		return -ENOMEM;
    374
    375	ad1836->regmap = devm_regmap_init_spi(spi, &ad1836_regmap_config);
    376	if (IS_ERR(ad1836->regmap))
    377		return PTR_ERR(ad1836->regmap);
    378
    379	ad1836->type = spi_get_device_id(spi)->driver_data;
    380
    381	spi_set_drvdata(spi, ad1836);
    382
    383	ret = devm_snd_soc_register_component(&spi->dev,
    384			&soc_component_dev_ad1836, &ad183x_dais[ad1836->type], 1);
    385	return ret;
    386}
    387
    388static const struct spi_device_id ad1836_ids[] = {
    389	{ "ad1835", AD1835 },
    390	{ "ad1836", AD1836 },
    391	{ "ad1837", AD1835 },
    392	{ "ad1838", AD1838 },
    393	{ "ad1839", AD1838 },
    394	{ },
    395};
    396MODULE_DEVICE_TABLE(spi, ad1836_ids);
    397
    398static struct spi_driver ad1836_spi_driver = {
    399	.driver = {
    400		.name	= "ad1836",
    401	},
    402	.probe		= ad1836_spi_probe,
    403	.id_table	= ad1836_ids,
    404};
    405
    406module_spi_driver(ad1836_spi_driver);
    407
    408MODULE_DESCRIPTION("ASoC ad1836 driver");
    409MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
    410MODULE_LICENSE("GPL");