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

jz4760.c (24720B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Ingenic JZ4760 CODEC driver
      4//
      5// Copyright (C) 2021, Christophe Branchereau <cbranchereau@gmail.com>
      6// Copyright (C) 2021, Paul Cercueil <paul@crapouillou.net>
      7
      8#include <linux/bitfield.h>
      9#include <linux/clk.h>
     10#include <linux/delay.h>
     11#include <linux/iopoll.h>
     12#include <linux/module.h>
     13#include <linux/regmap.h>
     14#include <linux/time64.h>
     15
     16#include <sound/pcm_params.h>
     17#include <sound/soc.h>
     18#include <sound/soc-dai.h>
     19#include <sound/soc-dapm.h>
     20#include <sound/tlv.h>
     21
     22#define ICDC_RGADW_OFFSET		0x00
     23#define ICDC_RGDATA_OFFSET		0x04
     24
     25/* ICDC internal register access control register(RGADW) */
     26#define ICDC_RGADW_RGWR			BIT(16)
     27#define	ICDC_RGADW_RGADDR_MASK		GENMASK(14, 8)
     28#define	ICDC_RGADW_RGDIN_MASK		GENMASK(7, 0)
     29
     30/* ICDC internal register data output register (RGDATA)*/
     31#define ICDC_RGDATA_IRQ			BIT(8)
     32#define ICDC_RGDATA_RGDOUT_MASK		GENMASK(7, 0)
     33
     34/* Internal register space, accessed through regmap */
     35enum {
     36	JZ4760_CODEC_REG_SR,
     37	JZ4760_CODEC_REG_AICR,
     38	JZ4760_CODEC_REG_CR1,
     39	JZ4760_CODEC_REG_CR2,
     40	JZ4760_CODEC_REG_CR3,
     41	JZ4760_CODEC_REG_CR4,
     42	JZ4760_CODEC_REG_CCR1,
     43	JZ4760_CODEC_REG_CCR2,
     44	JZ4760_CODEC_REG_PMR1,
     45	JZ4760_CODEC_REG_PMR2,
     46	JZ4760_CODEC_REG_ICR,
     47	JZ4760_CODEC_REG_IFR,
     48	JZ4760_CODEC_REG_GCR1,
     49	JZ4760_CODEC_REG_GCR2,
     50	JZ4760_CODEC_REG_GCR3,
     51	JZ4760_CODEC_REG_GCR4,
     52	JZ4760_CODEC_REG_GCR5,
     53	JZ4760_CODEC_REG_GCR6,
     54	JZ4760_CODEC_REG_GCR7,
     55	JZ4760_CODEC_REG_GCR8,
     56	JZ4760_CODEC_REG_GCR9,
     57	JZ4760_CODEC_REG_AGC1,
     58	JZ4760_CODEC_REG_AGC2,
     59	JZ4760_CODEC_REG_AGC3,
     60	JZ4760_CODEC_REG_AGC4,
     61	JZ4760_CODEC_REG_AGC5,
     62	JZ4760_CODEC_REG_MIX1,
     63	JZ4760_CODEC_REG_MIX2,
     64};
     65
     66#define REG_AICR_DAC_ADWL_MASK		GENMASK(7, 6)
     67#define REG_AICR_DAC_SERIAL		BIT(3)
     68#define REG_AICR_DAC_I2S		BIT(1)
     69
     70#define REG_AICR_ADC_ADWL_MASK		GENMASK(5, 4)
     71
     72#define REG_AICR_ADC_SERIAL		BIT(2)
     73#define REG_AICR_ADC_I2S		BIT(0)
     74
     75#define REG_CR1_HP_LOAD			BIT(7)
     76#define REG_CR1_HP_MUTE			BIT(5)
     77#define REG_CR1_LO_MUTE_OFFSET		4
     78#define REG_CR1_BTL_MUTE_OFFSET		3
     79#define REG_CR1_OUTSEL_OFFSET		0
     80#define REG_CR1_OUTSEL_MASK		GENMASK(1, REG_CR1_OUTSEL_OFFSET)
     81
     82#define REG_CR2_DAC_MONO		BIT(7)
     83#define REG_CR2_DAC_MUTE		BIT(5)
     84#define REG_CR2_DAC_NOMAD		BIT(1)
     85#define REG_CR2_DAC_RIGHT_ONLY		BIT(0)
     86
     87#define REG_CR3_ADC_INSEL_OFFSET	2
     88#define REG_CR3_ADC_INSEL_MASK		GENMASK(3, REG_CR3_ADC_INSEL_OFFSET)
     89#define REG_CR3_MICSTEREO_OFFSET	1
     90#define REG_CR3_MICDIFF_OFFSET		0
     91
     92#define REG_CR4_ADC_HPF_OFFSET		7
     93#define REG_CR4_ADC_RIGHT_ONLY		BIT(0)
     94
     95#define REG_CCR1_CRYSTAL_MASK		GENMASK(3, 0)
     96
     97#define REG_CCR2_DAC_FREQ_MASK		GENMASK(7, 4)
     98#define REG_CCR2_ADC_FREQ_MASK		GENMASK(3, 0)
     99
    100#define REG_PMR1_SB			BIT(7)
    101#define REG_PMR1_SB_SLEEP		BIT(6)
    102#define REG_PMR1_SB_AIP_OFFSET		5
    103#define REG_PMR1_SB_LINE_OFFSET		4
    104#define REG_PMR1_SB_MIC1_OFFSET		3
    105#define REG_PMR1_SB_MIC2_OFFSET		2
    106#define REG_PMR1_SB_BYPASS_OFFSET	1
    107#define REG_PMR1_SB_MICBIAS_OFFSET	0
    108
    109#define REG_PMR2_SB_ADC_OFFSET		4
    110#define REG_PMR2_SB_HP_OFFSET		3
    111#define REG_PMR2_SB_BTL_OFFSET		2
    112#define REG_PMR2_SB_LOUT_OFFSET		1
    113#define REG_PMR2_SB_DAC_OFFSET		0
    114
    115#define REG_ICR_INT_FORM_MASK		GENMASK(7, 6)
    116#define REG_ICR_ALL_MASK		GENMASK(5, 0)
    117#define REG_ICR_JACK_MASK		BIT(5)
    118#define REG_ICR_SCMC_MASK		BIT(4)
    119#define REG_ICR_RUP_MASK		BIT(3)
    120#define REG_ICR_RDO_MASK		BIT(2)
    121#define REG_ICR_GUP_MASK		BIT(1)
    122#define REG_ICR_GDO_MASK		BIT(0)
    123
    124#define REG_IFR_ALL_MASK		GENMASK(5, 0)
    125#define REG_IFR_JACK			BIT(6)
    126#define REG_IFR_JACK_EVENT		BIT(5)
    127#define REG_IFR_SCMC			BIT(4)
    128#define REG_IFR_RUP			BIT(3)
    129#define REG_IFR_RDO			BIT(2)
    130#define REG_IFR_GUP			BIT(1)
    131#define REG_IFR_GDO			BIT(0)
    132
    133#define REG_GCR_GAIN_OFFSET		0
    134#define REG_GCR_GAIN_MAX		0x1f
    135
    136#define REG_GCR_RL			BIT(7)
    137
    138#define REG_GCR_GIM1_MASK		GENMASK(5, 3)
    139#define REG_GCR_GIM2_MASK		GENMASK(2, 0)
    140#define REG_GCR_GIM_GAIN_MAX		7
    141
    142#define REG_AGC1_EN			BIT(7)
    143#define REG_AGC1_TARGET_MASK		GENMASK(5, 2)
    144
    145#define REG_AGC2_NG_THR_MASK		GENMASK(6, 4)
    146#define REG_AGC2_HOLD_MASK		GENMASK(3, 0)
    147
    148#define REG_AGC3_ATK_MASK		GENMASK(7, 4)
    149#define REG_AGC3_DCY_MASK		GENMASK(3, 0)
    150
    151#define REG_AGC4_AGC_MAX_MASK		GENMASK(4, 0)
    152
    153#define REG_AGC5_AGC_MIN_MASK		GENMASK(4, 0)
    154
    155#define REG_MIX1_MIX_REC_MASK		GENMASK(7, 6)
    156#define REG_MIX1_GIMIX_MASK		GENMASK(4, 0)
    157
    158#define REG_MIX2_DAC_MIX_MASK		GENMASK(7, 6)
    159#define REG_MIX2_GOMIX_MASK		GENMASK(4, 0)
    160
    161/* codec private data */
    162struct jz_codec {
    163	struct device *dev;
    164	struct regmap *regmap;
    165	void __iomem *base;
    166	struct clk *clk;
    167};
    168
    169static int jz4760_codec_set_bias_level(struct snd_soc_component *codec,
    170				       enum snd_soc_bias_level level)
    171{
    172	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
    173	struct regmap *regmap = jz_codec->regmap;
    174
    175	switch (level) {
    176	case SND_SOC_BIAS_PREPARE:
    177		/* Reset all interrupt flags. */
    178		regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK);
    179
    180		regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
    181		msleep(250);
    182		regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
    183		msleep(400);
    184		break;
    185	case SND_SOC_BIAS_STANDBY:
    186		regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
    187		regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
    188		break;
    189	default:
    190		break;
    191	}
    192
    193	return 0;
    194}
    195
    196static int jz4760_codec_startup(struct snd_pcm_substream *substream,
    197				struct snd_soc_dai *dai)
    198{
    199	struct snd_soc_component *codec = dai->component;
    200	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
    201	int ret = 0;
    202
    203	/*
    204	 * SYSCLK output from the codec to the AIC is required to keep the
    205	 * DMA transfer going during playback when all audible outputs have
    206	 * been disabled.
    207	 */
    208	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    209		ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
    210	return ret;
    211}
    212
    213static void jz4760_codec_shutdown(struct snd_pcm_substream *substream,
    214				  struct snd_soc_dai *dai)
    215{
    216	struct snd_soc_component *codec = dai->component;
    217	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
    218
    219	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    220		snd_soc_dapm_disable_pin(dapm, "SYSCLK");
    221}
    222
    223
    224static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream,
    225				    int cmd, struct snd_soc_dai *dai)
    226{
    227	struct snd_soc_component *codec = dai->component;
    228	int ret = 0;
    229
    230	switch (cmd) {
    231	case SNDRV_PCM_TRIGGER_START:
    232	case SNDRV_PCM_TRIGGER_RESUME:
    233	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
    234		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
    235			snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON);
    236		break;
    237	case SNDRV_PCM_TRIGGER_STOP:
    238	case SNDRV_PCM_TRIGGER_SUSPEND:
    239	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
    240		/* do nothing */
    241		break;
    242	default:
    243		ret = -EINVAL;
    244	}
    245
    246	return ret;
    247}
    248
    249static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
    250{
    251	struct snd_soc_component *codec = dai->component;
    252	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
    253	unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
    254	unsigned int val, reg;
    255	int change, err;
    256
    257	change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2,
    258					       REG_CR2_DAC_MUTE,
    259					       mute ? REG_CR2_DAC_MUTE : 0);
    260	if (change == 1) {
    261		regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val);
    262
    263		if (val & BIT(REG_PMR2_SB_DAC_OFFSET))
    264			return 1;
    265
    266		err = regmap_read_poll_timeout(jz_codec->regmap,
    267					       JZ4760_CODEC_REG_IFR,
    268					       val, val & gain_bit,
    269					       1000, 1 * USEC_PER_SEC);
    270		if (err) {
    271			dev_err(jz_codec->dev,
    272				"Timeout while setting digital mute: %d", err);
    273			return err;
    274		}
    275
    276		/* clear GUP/GDO flag */
    277		regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit);
    278	}
    279
    280	regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, &reg);
    281
    282	return 0;
    283}
    284
    285/* unit: 0.01dB */
    286static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100);
    287static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
    288static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100);
    289static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
    290
    291/* Unconditional controls. */
    292static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = {
    293	/* record gain control */
    294	SOC_DOUBLE_R_TLV("PCM Capture Volume",
    295			 JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8,
    296			 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv),
    297
    298	SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
    299			 JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3,
    300			 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
    301
    302	SOC_SINGLE("High-Pass Filter Capture Switch",
    303		   JZ4760_CODEC_REG_CR4,
    304		   REG_CR4_ADC_HPF_OFFSET, 1, 0),
    305};
    306
    307static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = {
    308	{
    309		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    310		.name = "Volume",
    311		.info = snd_soc_info_volsw,
    312		.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
    313			| SNDRV_CTL_ELEM_ACCESS_READWRITE,
    314		.tlv.p = dac_tlv,
    315		.get = snd_soc_dapm_get_volsw,
    316		.put = snd_soc_dapm_put_volsw,
    317		.private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6,
    318						    JZ4760_CODEC_REG_GCR5,
    319						    REG_GCR_GAIN_OFFSET,
    320						    REG_GCR_GAIN_MAX, 1),
    321	},
    322};
    323
    324static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = {
    325	{
    326		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    327		.name = "Volume",
    328		.info = snd_soc_info_volsw,
    329		.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
    330			| SNDRV_CTL_ELEM_ACCESS_READWRITE,
    331		.tlv.p = out_tlv,
    332		.get = snd_soc_dapm_get_volsw,
    333		.put = snd_soc_dapm_put_volsw,
    334		.private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2,
    335						    JZ4760_CODEC_REG_GCR1,
    336						    REG_GCR_GAIN_OFFSET,
    337						    REG_GCR_GAIN_MAX, 1),
    338	},
    339};
    340
    341static int hpout_event(struct snd_soc_dapm_widget *w,
    342		       struct snd_kcontrol *kcontrol, int event)
    343{
    344	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    345	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
    346	unsigned int val;
    347	int err;
    348
    349	switch (event) {
    350	case SND_SOC_DAPM_PRE_PMU:
    351		/* unmute HP */
    352		regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
    353				  REG_CR1_HP_MUTE);
    354		break;
    355
    356	case SND_SOC_DAPM_POST_PMU:
    357		/* wait for ramp-up complete (RUP) */
    358		err = regmap_read_poll_timeout(jz_codec->regmap,
    359					       JZ4760_CODEC_REG_IFR,
    360					       val, val & REG_IFR_RUP,
    361					       1000, 1 * USEC_PER_SEC);
    362		if (err) {
    363			dev_err(jz_codec->dev, "RUP timeout: %d", err);
    364			return err;
    365		}
    366
    367		/* clear RUP flag */
    368		regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
    369				REG_IFR_RUP);
    370
    371		break;
    372
    373	case SND_SOC_DAPM_POST_PMD:
    374		/* mute HP */
    375		regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
    376				REG_CR1_HP_MUTE);
    377
    378		err = regmap_read_poll_timeout(jz_codec->regmap,
    379					       JZ4760_CODEC_REG_IFR,
    380					       val, val & REG_IFR_RDO,
    381					       1000, 1 * USEC_PER_SEC);
    382		if (err) {
    383			dev_err(jz_codec->dev, "RDO timeout: %d", err);
    384			return err;
    385		}
    386
    387		/* clear RDO flag */
    388		regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
    389				REG_IFR_RDO);
    390
    391		break;
    392	}
    393
    394	return 0;
    395}
    396
    397static const char * const jz4760_codec_hp_texts[] = {
    398	"PCM", "Line In", "Mic 1", "Mic 2"
    399};
    400
    401static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 };
    402
    403static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum,
    404				  JZ4760_CODEC_REG_CR1,
    405				  REG_CR1_OUTSEL_OFFSET,
    406				  REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET,
    407				  jz4760_codec_hp_texts,
    408				  jz4760_codec_hp_values);
    409static const struct snd_kcontrol_new jz4760_codec_hp_source =
    410			SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum);
    411
    412static const char * const jz4760_codec_cap_texts[] = {
    413	"Line In", "Mic 1", "Mic 2"
    414};
    415
    416static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 };
    417
    418static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum,
    419				  JZ4760_CODEC_REG_CR3,
    420				  REG_CR3_ADC_INSEL_OFFSET,
    421				  REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET,
    422				  jz4760_codec_cap_texts,
    423				  jz4760_codec_cap_values);
    424static const struct snd_kcontrol_new jz4760_codec_cap_source =
    425			SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum);
    426
    427static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = {
    428	SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3,
    429			REG_CR3_MICSTEREO_OFFSET, 1, 0),
    430};
    431
    432static const struct snd_kcontrol_new jz4760_codec_line_out_switch =
    433	SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
    434			REG_CR1_LO_MUTE_OFFSET, 0, 0);
    435static const struct snd_kcontrol_new jz4760_codec_btl_out_switch =
    436	SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
    437			REG_CR1_BTL_MUTE_OFFSET, 0, 0);
    438
    439static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = {
    440	SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2,
    441			   REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event,
    442			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
    443			   SND_SOC_DAPM_POST_PMD),
    444
    445	SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2,
    446			    REG_PMR2_SB_LOUT_OFFSET, 1,
    447			    &jz4760_codec_line_out_switch),
    448
    449	SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2,
    450			    REG_PMR2_SB_BTL_OFFSET, 1,
    451			    &jz4760_codec_btl_out_switch),
    452
    453	SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1,
    454			 REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0),
    455
    456	SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
    457			 &jz4760_codec_hp_source),
    458
    459	SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
    460			 &jz4760_codec_cap_source),
    461
    462	SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1,
    463			 REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0),
    464
    465	SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1,
    466			 REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0),
    467
    468	SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3,
    469			 REG_CR3_MICDIFF_OFFSET, 0, NULL, 0),
    470
    471	SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
    472			   jz4760_codec_mic_controls,
    473			   ARRAY_SIZE(jz4760_codec_mic_controls)),
    474
    475	SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1,
    476			 REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0),
    477
    478	SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2,
    479			 REG_PMR2_SB_ADC_OFFSET, 1),
    480
    481	SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2,
    482			 REG_PMR2_SB_DAC_OFFSET, 1),
    483
    484	SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
    485			   jz4760_codec_pcm_playback_controls,
    486			   ARRAY_SIZE(jz4760_codec_pcm_playback_controls)),
    487
    488	SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
    489			   jz4760_codec_hp_playback_controls,
    490			   ARRAY_SIZE(jz4760_codec_hp_playback_controls)),
    491
    492	SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1,
    493			    REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
    494
    495	SND_SOC_DAPM_INPUT("MIC1P"),
    496	SND_SOC_DAPM_INPUT("MIC1N"),
    497	SND_SOC_DAPM_INPUT("MIC2P"),
    498	SND_SOC_DAPM_INPUT("MIC2N"),
    499
    500	SND_SOC_DAPM_INPUT("LLINEIN"),
    501	SND_SOC_DAPM_INPUT("RLINEIN"),
    502
    503	SND_SOC_DAPM_OUTPUT("LHPOUT"),
    504	SND_SOC_DAPM_OUTPUT("RHPOUT"),
    505
    506	SND_SOC_DAPM_OUTPUT("LOUT"),
    507	SND_SOC_DAPM_OUTPUT("ROUT"),
    508
    509	SND_SOC_DAPM_OUTPUT("BTLP"),
    510	SND_SOC_DAPM_OUTPUT("BTLN"),
    511
    512	SND_SOC_DAPM_OUTPUT("SYSCLK"),
    513};
    514
    515/* Unconditional routes. */
    516static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = {
    517	{ "Mic 1", NULL, "MIC1P" },
    518	{ "Mic Diff", NULL, "MIC1N" },
    519	{ "Mic 1", NULL, "Mic Diff" },
    520	{ "Mic 2", NULL, "MIC2P" },
    521	{ "Mic Diff", NULL, "MIC2N" },
    522	{ "Mic 2", NULL, "Mic Diff" },
    523
    524	{ "Line In", NULL, "LLINEIN" },
    525	{ "Line In", NULL, "RLINEIN" },
    526
    527	{ "Mic", "Stereo Capture Switch", "Mic 1" },
    528	{ "Mic", "Stereo Capture Switch", "Mic 2" },
    529	{ "Headphones Source", "Mic 1", "Mic" },
    530	{ "Headphones Source", "Mic 2", "Mic" },
    531	{ "Capture Source", "Mic 1", "Mic" },
    532	{ "Capture Source", "Mic 2", "Mic" },
    533
    534	{ "Capture Source", "Line In", "Line In" },
    535	{ "Capture Source", "Mic 1", "Mic 1" },
    536	{ "Capture Source", "Mic 2", "Mic 2" },
    537	{ "ADC", NULL, "Capture Source" },
    538
    539	{ "Line In Bypass", NULL, "Line In" },
    540
    541	{ "Headphones Source", "Mic 1", "Mic 1" },
    542	{ "Headphones Source", "Mic 2", "Mic 2" },
    543	{ "Headphones Source", "Line In", "Line In Bypass" },
    544	{ "Headphones Source", "PCM", "Headphones Playback" },
    545	{ "HP Out", NULL, "Headphones Source" },
    546
    547	{ "LHPOUT", NULL, "HP Out" },
    548	{ "RHPOUT", NULL, "HP Out" },
    549	{ "Line Out", "Switch", "HP Out" },
    550
    551	{ "LOUT", NULL, "Line Out" },
    552	{ "ROUT", NULL, "Line Out" },
    553	{ "BTL Out", "Switch", "Line Out" },
    554
    555	{ "BTLP", NULL, "BTL Out"},
    556	{ "BTLN", NULL, "BTL Out"},
    557
    558	{ "PCM Playback", "Volume", "DAC" },
    559	{ "Headphones Playback", "Volume", "PCM Playback" },
    560
    561	{ "SYSCLK", NULL, "DAC" },
    562};
    563
    564static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec)
    565{
    566	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
    567	struct regmap *regmap = jz_codec->regmap;
    568
    569	/* Collect updates for later sending. */
    570	regcache_cache_only(regmap, true);
    571
    572	/* default Amp output to PCM */
    573	regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK);
    574
    575	/* Disable stereo mic */
    576	regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
    577			  BIT(REG_CR3_MICSTEREO_OFFSET));
    578
    579	/* Set mic 1 as default source for ADC */
    580	regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
    581			  REG_CR3_ADC_INSEL_MASK);
    582
    583	/* ADC/DAC: serial + i2s */
    584	regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR,
    585			REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S |
    586			REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
    587
    588	/* The generated IRQ is a high level */
    589	regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
    590	regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK,
    591			   REG_ICR_JACK_MASK | REG_ICR_RUP_MASK |
    592			   REG_ICR_RDO_MASK  | REG_ICR_GUP_MASK |
    593			   REG_ICR_GDO_MASK);
    594
    595	/* 12M oscillator */
    596	regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK);
    597
    598	/* 0: 16ohm/220uF, 1: 10kohm/1uF */
    599	regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD);
    600
    601	/* default to NOMAD */
    602	regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2,
    603			REG_CR2_DAC_NOMAD);
    604
    605	/* disable automatic gain */
    606	regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN);
    607
    608	/* Independent L/R DAC gain control */
    609	regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5,
    610			  REG_GCR_RL);
    611
    612	/* Send collected updates. */
    613	regcache_cache_only(regmap, false);
    614	regcache_sync(regmap);
    615}
    616
    617static int jz4760_codec_codec_probe(struct snd_soc_component *codec)
    618{
    619	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
    620
    621	clk_prepare_enable(jz_codec->clk);
    622
    623	jz4760_codec_codec_init_regs(codec);
    624
    625	return 0;
    626}
    627
    628static void jz4760_codec_codec_remove(struct snd_soc_component *codec)
    629{
    630	struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
    631
    632	clk_disable_unprepare(jz_codec->clk);
    633}
    634
    635static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = {
    636	.probe			= jz4760_codec_codec_probe,
    637	.remove			= jz4760_codec_codec_remove,
    638	.set_bias_level		= jz4760_codec_set_bias_level,
    639	.controls		= jz4760_codec_snd_controls,
    640	.num_controls		= ARRAY_SIZE(jz4760_codec_snd_controls),
    641	.dapm_widgets		= jz4760_codec_dapm_widgets,
    642	.num_dapm_widgets	= ARRAY_SIZE(jz4760_codec_dapm_widgets),
    643	.dapm_routes		= jz4760_codec_dapm_routes,
    644	.num_dapm_routes	= ARRAY_SIZE(jz4760_codec_dapm_routes),
    645	.suspend_bias_off	= 1,
    646	.use_pmdown_time	= 1,
    647};
    648
    649static const unsigned int jz4760_codec_sample_rates[] = {
    650	96000, 48000, 44100, 32000,
    651	24000, 22050, 16000, 12000,
    652	11025, 9600, 8000,
    653};
    654
    655static int jz4760_codec_hw_params(struct snd_pcm_substream *substream,
    656				  struct snd_pcm_hw_params *params,
    657				  struct snd_soc_dai *dai)
    658{
    659	struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
    660	unsigned int rate, bit_width;
    661
    662	switch (params_format(params)) {
    663	case SNDRV_PCM_FORMAT_S16_LE:
    664		bit_width = 0;
    665		break;
    666	case SNDRV_PCM_FORMAT_S18_3LE:
    667		bit_width = 1;
    668		break;
    669	case SNDRV_PCM_FORMAT_S20_3LE:
    670		bit_width = 2;
    671		break;
    672	case SNDRV_PCM_FORMAT_S24_3LE:
    673		bit_width = 3;
    674		break;
    675	default:
    676		return -EINVAL;
    677	}
    678
    679	for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) {
    680		if (jz4760_codec_sample_rates[rate] == params_rate(params))
    681			break;
    682	}
    683
    684	if (rate == ARRAY_SIZE(jz4760_codec_sample_rates))
    685		return -EINVAL;
    686
    687	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
    688		regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
    689				   REG_AICR_DAC_ADWL_MASK,
    690				   FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width));
    691		regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
    692				   REG_CCR2_DAC_FREQ_MASK,
    693				   FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate));
    694	} else {
    695		regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
    696				   REG_AICR_ADC_ADWL_MASK,
    697				   FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width));
    698		regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
    699				   REG_CCR2_ADC_FREQ_MASK,
    700				   FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate));
    701	}
    702
    703	return 0;
    704}
    705
    706static const struct snd_soc_dai_ops jz4760_codec_dai_ops = {
    707	.startup	= jz4760_codec_startup,
    708	.shutdown	= jz4760_codec_shutdown,
    709	.hw_params	= jz4760_codec_hw_params,
    710	.trigger	= jz4760_codec_pcm_trigger,
    711	.mute_stream	= jz4760_codec_mute_stream,
    712	.no_capture_mute = 1,
    713};
    714
    715#define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | \
    716			  SNDRV_PCM_FMTBIT_S18_3LE | \
    717			  SNDRV_PCM_FMTBIT_S20_3LE | \
    718			  SNDRV_PCM_FMTBIT_S24_3LE)
    719
    720static struct snd_soc_dai_driver jz4760_codec_dai = {
    721	.name = "jz4760-hifi",
    722	.playback = {
    723		.stream_name = "Playback",
    724		.channels_min = 2,
    725		.channels_max = 2,
    726		.rates = SNDRV_PCM_RATE_8000_96000,
    727		.formats = JZ_CODEC_FORMATS,
    728	},
    729	.capture = {
    730		.stream_name = "Capture",
    731		.channels_min = 2,
    732		.channels_max = 2,
    733		.rates = SNDRV_PCM_RATE_8000_96000,
    734		.formats = JZ_CODEC_FORMATS,
    735	},
    736	.ops = &jz4760_codec_dai_ops,
    737};
    738
    739static bool jz4760_codec_volatile(struct device *dev, unsigned int reg)
    740{
    741	return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR;
    742}
    743
    744static bool jz4760_codec_writeable(struct device *dev, unsigned int reg)
    745{
    746	switch (reg) {
    747	case JZ4760_CODEC_REG_SR:
    748		return false;
    749	default:
    750		return true;
    751	}
    752}
    753
    754static int jz4760_codec_io_wait(struct jz_codec *codec)
    755{
    756	u32 reg;
    757
    758	return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
    759				  !(reg & ICDC_RGADW_RGWR),
    760				  1000, 1 * USEC_PER_SEC);
    761}
    762
    763static int jz4760_codec_reg_read(void *context, unsigned int reg,
    764				 unsigned int *val)
    765{
    766	struct jz_codec *codec = context;
    767	unsigned int i;
    768	u32 tmp;
    769	int ret;
    770
    771	ret = jz4760_codec_io_wait(codec);
    772	if (ret)
    773		return ret;
    774
    775	tmp = readl(codec->base + ICDC_RGADW_OFFSET);
    776	tmp &= ~ICDC_RGADW_RGADDR_MASK;
    777	tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg);
    778	writel(tmp, codec->base + ICDC_RGADW_OFFSET);
    779
    780	/* wait 6+ cycles */
    781	for (i = 0; i < 6; i++)
    782		*val = readl(codec->base + ICDC_RGDATA_OFFSET) &
    783			ICDC_RGDATA_RGDOUT_MASK;
    784
    785	return 0;
    786}
    787
    788static int jz4760_codec_reg_write(void *context, unsigned int reg,
    789				  unsigned int val)
    790{
    791	struct jz_codec *codec = context;
    792	int ret;
    793
    794	ret = jz4760_codec_io_wait(codec);
    795	if (ret)
    796		return ret;
    797
    798	writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val,
    799	       codec->base + ICDC_RGADW_OFFSET);
    800
    801	ret = jz4760_codec_io_wait(codec);
    802	if (ret)
    803		return ret;
    804
    805	return 0;
    806}
    807
    808static const u8 jz4760_codec_reg_defaults[] = {
    809	0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00,
    810	0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06,
    811	0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44,
    812	0x1F, 0x00, 0x00, 0x00
    813};
    814
    815static struct regmap_config jz4760_codec_regmap_config = {
    816	.reg_bits = 7,
    817	.val_bits = 8,
    818
    819	.max_register = JZ4760_CODEC_REG_MIX2,
    820	.volatile_reg = jz4760_codec_volatile,
    821	.writeable_reg = jz4760_codec_writeable,
    822
    823	.reg_read = jz4760_codec_reg_read,
    824	.reg_write = jz4760_codec_reg_write,
    825
    826	.reg_defaults_raw = jz4760_codec_reg_defaults,
    827	.num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults),
    828	.cache_type = REGCACHE_FLAT,
    829};
    830
    831static int jz4760_codec_probe(struct platform_device *pdev)
    832{
    833	struct device *dev = &pdev->dev;
    834	struct jz_codec *codec;
    835	int ret;
    836
    837	codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
    838	if (!codec)
    839		return -ENOMEM;
    840
    841	codec->dev = dev;
    842
    843	codec->base = devm_platform_ioremap_resource(pdev, 0);
    844	if (IS_ERR(codec->base))
    845		return PTR_ERR(codec->base);
    846
    847	codec->regmap = devm_regmap_init(dev, NULL, codec,
    848					&jz4760_codec_regmap_config);
    849	if (IS_ERR(codec->regmap))
    850		return PTR_ERR(codec->regmap);
    851
    852	codec->clk = devm_clk_get(dev, "aic");
    853	if (IS_ERR(codec->clk))
    854		return PTR_ERR(codec->clk);
    855
    856	platform_set_drvdata(pdev, codec);
    857
    858	ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev,
    859					      &jz4760_codec_dai, 1);
    860	if (ret) {
    861		dev_err(dev, "Failed to register codec: %d\n", ret);
    862		return ret;
    863	}
    864
    865	return 0;
    866}
    867
    868static const struct of_device_id jz4760_codec_of_matches[] = {
    869	{ .compatible = "ingenic,jz4760-codec", },
    870	{ /* sentinel */ }
    871};
    872MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches);
    873
    874static struct platform_driver jz4760_codec_driver = {
    875	.probe			= jz4760_codec_probe,
    876	.driver			= {
    877		.name		= "jz4760-codec",
    878		.of_match_table = jz4760_codec_of_matches,
    879	},
    880};
    881module_platform_driver(jz4760_codec_driver);
    882
    883MODULE_DESCRIPTION("JZ4760 SoC internal codec driver");
    884MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
    885MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
    886MODULE_LICENSE("GPL v2");