Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: add es8328 codec driver

Add a codec driver for the Everest ES8328. It supports two separate audio
outputs and two separate audio inputs.

Signed-off-by: Sean Cross <xobs@kosagi.com>
Signed-off-by: Mark Brown <broonie@linaro.org>

authored by

Sean Cross and committed by
Mark Brown
567e4f98 d4f7facd

+1236
+38
Documentation/devicetree/bindings/sound/es8328.txt
··· 1 + Everest ES8328 audio CODEC 2 + 3 + This device supports both I2C and SPI. 4 + 5 + Required properties: 6 + 7 + - compatible : "everest,es8328" 8 + - DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V 9 + - AVDD-supply : Regulator providing analog supply voltage 3.3V 10 + - PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V 11 + - IPVDD-supply : Regulator providing analog output voltage 3.3V 12 + - clocks : A 22.5792 or 11.2896 MHz clock 13 + - reg : the I2C address of the device for I2C, the chip select number for SPI 14 + 15 + Pins on the device (for linking into audio routes): 16 + 17 + * LOUT1 18 + * LOUT2 19 + * ROUT1 20 + * ROUT2 21 + * LINPUT1 22 + * RINPUT1 23 + * LINPUT2 24 + * RINPUT2 25 + * Mic Bias 26 + 27 + 28 + Example: 29 + 30 + codec: es8328@11 { 31 + compatible = "everest,es8328"; 32 + DVDD-supply = <&reg_3p3v>; 33 + AVDD-supply = <&reg_3p3v>; 34 + PVDD-supply = <&reg_3p3v>; 35 + HPVDD-supply = <&reg_3p3v>; 36 + clocks = <&clks 169>; 37 + reg = <0x11>; 38 + };
+13
sound/soc/codecs/Kconfig
··· 57 57 select SND_SOC_DA732X if I2C 58 58 select SND_SOC_DA9055 if I2C 59 59 select SND_SOC_BT_SCO 60 + select SND_SOC_ES8328_SPI if SPI_MASTER 61 + select SND_SOC_ES8328_I2C if I2C 60 62 select SND_SOC_ISABELLE if I2C 61 63 select SND_SOC_JZ4740_CODEC 62 64 select SND_SOC_LM4857 if I2C ··· 406 404 407 405 config SND_SOC_HDMI_CODEC 408 406 tristate "HDMI stub CODEC" 407 + 408 + config SND_SOC_ES8328 409 + tristate "Everest Semi ES8328 CODEC" 410 + 411 + config SND_SOC_ES8328_I2C 412 + tristate 413 + select SND_SOC_ES8328 414 + 415 + config SND_SOC_ES8328_SPI 416 + tristate 417 + select SND_SOC_ES8328 409 418 410 419 config SND_SOC_ISABELLE 411 420 tristate
+6
sound/soc/codecs/Makefile
··· 49 49 snd-soc-da9055-objs := da9055.o 50 50 snd-soc-bt-sco-objs := bt-sco.o 51 51 snd-soc-dmic-objs := dmic.o 52 + snd-soc-es8328-objs := es8328.o 53 + snd-soc-es8328-i2c-objs := es8328-i2c.o 54 + snd-soc-es8328-spi-objs := es8328-spi.o 52 55 snd-soc-isabelle-objs := isabelle.o 53 56 snd-soc-jz4740-codec-objs := jz4740.o 54 57 snd-soc-l3-objs := l3.o ··· 223 220 obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 224 221 obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o 225 222 obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 223 + obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o 224 + obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o 225 + obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o 226 226 obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o 227 227 obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 228 228 obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
+60
sound/soc/codecs/es8328-i2c.c
··· 1 + /* 2 + * es8328-i2c.c -- ES8328 ALSA SoC I2C Audio driver 3 + * 4 + * Copyright 2014 Sutajio Ko-Usagi PTE LTD 5 + * 6 + * Author: Sean Cross <xobs@kosagi.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/i2c.h> 15 + #include <linux/regmap.h> 16 + 17 + #include <sound/soc.h> 18 + 19 + #include "es8328.h" 20 + 21 + static const struct i2c_device_id es8328_id[] = { 22 + { "everest,es8328", 0 }, 23 + { } 24 + }; 25 + MODULE_DEVICE_TABLE(i2c, es8328_id); 26 + 27 + static const struct of_device_id es8328_of_match[] = { 28 + { .compatible = "everest,es8328", }, 29 + { } 30 + }; 31 + MODULE_DEVICE_TABLE(of, es8328_of_match); 32 + 33 + static int es8328_i2c_probe(struct i2c_client *i2c, 34 + const struct i2c_device_id *id) 35 + { 36 + return es8328_probe(&i2c->dev, 37 + devm_regmap_init_i2c(i2c, &es8328_regmap_config)); 38 + } 39 + 40 + static int es8328_i2c_remove(struct i2c_client *i2c) 41 + { 42 + snd_soc_unregister_codec(&i2c->dev); 43 + return 0; 44 + } 45 + 46 + static struct i2c_driver es8328_i2c_driver = { 47 + .driver = { 48 + .name = "es8328", 49 + .of_match_table = es8328_of_match, 50 + }, 51 + .probe = es8328_i2c_probe, 52 + .remove = es8328_i2c_remove, 53 + .id_table = es8328_id, 54 + }; 55 + 56 + module_i2c_driver(es8328_i2c_driver); 57 + 58 + MODULE_DESCRIPTION("ASoC ES8328 audio CODEC I2C driver"); 59 + MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); 60 + MODULE_LICENSE("GPL");
+49
sound/soc/codecs/es8328-spi.c
··· 1 + /* 2 + * es8328.c -- ES8328 ALSA SoC SPI Audio driver 3 + * 4 + * Copyright 2014 Sutajio Ko-Usagi PTE LTD 5 + * 6 + * Author: Sean Cross <xobs@kosagi.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/regmap.h> 15 + #include <linux/spi/spi.h> 16 + #include <sound/soc.h> 17 + #include "es8328.h" 18 + 19 + static const struct of_device_id es8328_of_match[] = { 20 + { .compatible = "everest,es8328", }, 21 + { } 22 + }; 23 + MODULE_DEVICE_TABLE(of, es8328_of_match); 24 + 25 + static int es8328_spi_probe(struct spi_device *spi) 26 + { 27 + return es8328_probe(&spi->dev, 28 + devm_regmap_init_spi(spi, &es8328_regmap_config)); 29 + } 30 + 31 + static int es8328_spi_remove(struct spi_device *spi) 32 + { 33 + snd_soc_unregister_codec(&spi->dev); 34 + return 0; 35 + } 36 + 37 + static struct spi_driver es8328_spi_driver = { 38 + .driver = { 39 + .name = "es8328", 40 + .of_match_table = es8328_of_match, 41 + }, 42 + .probe = es8328_spi_probe, 43 + .remove = es8328_spi_remove, 44 + }; 45 + 46 + module_spi_driver(es8328_spi_driver); 47 + MODULE_DESCRIPTION("ASoC ES8328 audio CODEC SPI driver"); 48 + MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); 49 + MODULE_LICENSE("GPL");
+756
sound/soc/codecs/es8328.c
··· 1 + /* 2 + * es8328.c -- ES8328 ALSA SoC Audio driver 3 + * 4 + * Copyright 2014 Sutajio Ko-Usagi PTE LTD 5 + * 6 + * Author: Sean Cross <xobs@kosagi.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/clk.h> 14 + #include <linux/delay.h> 15 + #include <linux/of_device.h> 16 + #include <linux/module.h> 17 + #include <linux/pm.h> 18 + #include <linux/regmap.h> 19 + #include <linux/slab.h> 20 + #include <linux/regulator/consumer.h> 21 + #include <sound/core.h> 22 + #include <sound/initval.h> 23 + #include <sound/pcm.h> 24 + #include <sound/pcm_params.h> 25 + #include <sound/soc.h> 26 + #include <sound/tlv.h> 27 + #include "es8328.h" 28 + 29 + #define ES8328_SYSCLK_RATE_1X 11289600 30 + #define ES8328_SYSCLK_RATE_2X 22579200 31 + 32 + /* Run the codec at 22.5792 or 11.2896 MHz to support these rates */ 33 + static struct { 34 + int rate; 35 + u8 ratio; 36 + } mclk_ratios[] = { 37 + { 8000, 9 }, 38 + {11025, 7 }, 39 + {22050, 4 }, 40 + {44100, 2 }, 41 + }; 42 + 43 + /* regulator supplies for sgtl5000, VDDD is an optional external supply */ 44 + enum sgtl5000_regulator_supplies { 45 + DVDD, 46 + AVDD, 47 + PVDD, 48 + HPVDD, 49 + ES8328_SUPPLY_NUM 50 + }; 51 + 52 + /* vddd is optional supply */ 53 + static const char * const supply_names[ES8328_SUPPLY_NUM] = { 54 + "DVDD", 55 + "AVDD", 56 + "PVDD", 57 + "HPVDD", 58 + }; 59 + 60 + #define ES8328_RATES (SNDRV_PCM_RATE_44100 | \ 61 + SNDRV_PCM_RATE_22050 | \ 62 + SNDRV_PCM_RATE_11025) 63 + #define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) 64 + 65 + struct es8328_priv { 66 + struct regmap *regmap; 67 + struct clk *clk; 68 + int playback_fs; 69 + bool deemph; 70 + struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; 71 + }; 72 + 73 + /* 74 + * ES8328 Controls 75 + */ 76 + 77 + static const char * const adcpol_txt[] = {"Normal", "L Invert", "R Invert", 78 + "L + R Invert"}; 79 + static SOC_ENUM_SINGLE_DECL(adcpol, 80 + ES8328_ADCCONTROL6, 6, adcpol_txt); 81 + 82 + static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); 83 + static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0); 84 + static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); 85 + static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); 86 + static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); 87 + 88 + static const int deemph_settings[] = { 0, 32000, 44100, 48000 }; 89 + 90 + static int es8328_set_deemph(struct snd_soc_codec *codec) 91 + { 92 + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 93 + int val, i, best; 94 + 95 + /* 96 + * If we're using deemphasis select the nearest available sample 97 + * rate. 98 + */ 99 + if (es8328->deemph) { 100 + best = 1; 101 + for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) { 102 + if (abs(deemph_settings[i] - es8328->playback_fs) < 103 + abs(deemph_settings[best] - es8328->playback_fs)) 104 + best = i; 105 + } 106 + 107 + val = best << 1; 108 + } else { 109 + val = 0; 110 + } 111 + 112 + dev_dbg(codec->dev, "Set deemphasis %d\n", val); 113 + 114 + return snd_soc_update_bits(codec, ES8328_DACCONTROL6, 0x6, val); 115 + } 116 + 117 + static int es8328_get_deemph(struct snd_kcontrol *kcontrol, 118 + struct snd_ctl_elem_value *ucontrol) 119 + { 120 + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 121 + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 122 + 123 + ucontrol->value.enumerated.item[0] = es8328->deemph; 124 + return 0; 125 + } 126 + 127 + static int es8328_put_deemph(struct snd_kcontrol *kcontrol, 128 + struct snd_ctl_elem_value *ucontrol) 129 + { 130 + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 131 + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 132 + int deemph = ucontrol->value.enumerated.item[0]; 133 + int ret; 134 + 135 + if (deemph > 1) 136 + return -EINVAL; 137 + 138 + ret = es8328_set_deemph(codec); 139 + if (ret < 0) 140 + return ret; 141 + 142 + es8328->deemph = deemph; 143 + 144 + return 0; 145 + } 146 + 147 + 148 + 149 + static const struct snd_kcontrol_new es8328_snd_controls[] = { 150 + SOC_DOUBLE_R_TLV("Capture Digital Volume", 151 + ES8328_ADCCONTROL8, ES8328_ADCCONTROL9, 152 + 0, 0xc0, 1, dac_adc_tlv), 153 + SOC_SINGLE("Capture ZC Switch", ES8328_ADCCONTROL7, 6, 1, 0), 154 + 155 + SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, 156 + es8328_get_deemph, es8328_put_deemph), 157 + 158 + SOC_ENUM("Capture Polarity", adcpol), 159 + 160 + SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", 161 + ES8328_DACCONTROL17, 3, 7, 1, bypass_tlv), 162 + SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", 163 + ES8328_DACCONTROL19, 3, 7, 1, bypass_tlv), 164 + SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", 165 + ES8328_DACCONTROL18, 3, 7, 1, bypass_tlv), 166 + SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", 167 + ES8328_DACCONTROL20, 3, 7, 1, bypass_tlv), 168 + 169 + SOC_DOUBLE_R_TLV("PCM Volume", 170 + ES8328_LDACVOL, ES8328_RDACVOL, 171 + 0, ES8328_DACVOL_MAX, 1, dac_adc_tlv), 172 + 173 + SOC_DOUBLE_R_TLV("Output 1 Playback Volume", 174 + ES8328_LOUT1VOL, ES8328_ROUT1VOL, 175 + 0, ES8328_OUT1VOL_MAX, 0, play_tlv), 176 + 177 + SOC_DOUBLE_R_TLV("Output 2 Playback Volume", 178 + ES8328_LOUT2VOL, ES8328_ROUT2VOL, 179 + 0, ES8328_OUT2VOL_MAX, 0, play_tlv), 180 + 181 + SOC_DOUBLE_TLV("Mic PGA Volume", ES8328_ADCCONTROL1, 182 + 4, 0, 8, 0, mic_tlv), 183 + }; 184 + 185 + /* 186 + * DAPM Controls 187 + */ 188 + 189 + static const char * const es8328_line_texts[] = { 190 + "Line 1", "Line 2", "PGA", "Differential"}; 191 + 192 + static const struct soc_enum es8328_lline_enum = 193 + SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 3, 194 + ARRAY_SIZE(es8328_line_texts), 195 + es8328_line_texts); 196 + static const struct snd_kcontrol_new es8328_left_line_controls = 197 + SOC_DAPM_ENUM("Route", es8328_lline_enum); 198 + 199 + static const struct soc_enum es8328_rline_enum = 200 + SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 0, 201 + ARRAY_SIZE(es8328_line_texts), 202 + es8328_line_texts); 203 + static const struct snd_kcontrol_new es8328_right_line_controls = 204 + SOC_DAPM_ENUM("Route", es8328_lline_enum); 205 + 206 + /* Left Mixer */ 207 + static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { 208 + SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 8, 1, 0), 209 + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 7, 1, 0), 210 + SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 8, 1, 0), 211 + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 7, 1, 0), 212 + }; 213 + 214 + /* Right Mixer */ 215 + static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { 216 + SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 8, 1, 0), 217 + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 7, 1, 0), 218 + SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 8, 1, 0), 219 + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 7, 1, 0), 220 + }; 221 + 222 + static const char * const es8328_pga_sel[] = { 223 + "Line 1", "Line 2", "Line 3", "Differential"}; 224 + 225 + /* Left PGA Mux */ 226 + static const struct soc_enum es8328_lpga_enum = 227 + SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 6, 228 + ARRAY_SIZE(es8328_pga_sel), 229 + es8328_pga_sel); 230 + static const struct snd_kcontrol_new es8328_left_pga_controls = 231 + SOC_DAPM_ENUM("Route", es8328_lpga_enum); 232 + 233 + /* Right PGA Mux */ 234 + static const struct soc_enum es8328_rpga_enum = 235 + SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 4, 236 + ARRAY_SIZE(es8328_pga_sel), 237 + es8328_pga_sel); 238 + static const struct snd_kcontrol_new es8328_right_pga_controls = 239 + SOC_DAPM_ENUM("Route", es8328_rpga_enum); 240 + 241 + /* Differential Mux */ 242 + static const char * const es8328_diff_sel[] = {"Line 1", "Line 2"}; 243 + static SOC_ENUM_SINGLE_DECL(diffmux, 244 + ES8328_ADCCONTROL3, 7, es8328_diff_sel); 245 + static const struct snd_kcontrol_new es8328_diffmux_controls = 246 + SOC_DAPM_ENUM("Route", diffmux); 247 + 248 + /* Mono ADC Mux */ 249 + static const char * const es8328_mono_mux[] = {"Stereo", "Mono (Left)", 250 + "Mono (Right)", "Digital Mono"}; 251 + static SOC_ENUM_SINGLE_DECL(monomux, 252 + ES8328_ADCCONTROL3, 3, es8328_mono_mux); 253 + static const struct snd_kcontrol_new es8328_monomux_controls = 254 + SOC_DAPM_ENUM("Route", monomux); 255 + 256 + static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { 257 + SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, 258 + &es8328_diffmux_controls), 259 + SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, 260 + &es8328_monomux_controls), 261 + SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, 262 + &es8328_monomux_controls), 263 + 264 + SND_SOC_DAPM_MUX("Left PGA Mux", ES8328_ADCPOWER, 265 + ES8328_ADCPOWER_AINL_OFF, 1, 266 + &es8328_left_pga_controls), 267 + SND_SOC_DAPM_MUX("Right PGA Mux", ES8328_ADCPOWER, 268 + ES8328_ADCPOWER_AINR_OFF, 1, 269 + &es8328_right_pga_controls), 270 + 271 + SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, 272 + &es8328_left_line_controls), 273 + SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, 274 + &es8328_right_line_controls), 275 + 276 + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8328_ADCPOWER, 277 + ES8328_ADCPOWER_ADCR_OFF, 1), 278 + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ES8328_ADCPOWER, 279 + ES8328_ADCPOWER_ADCL_OFF, 1), 280 + 281 + SND_SOC_DAPM_SUPPLY("Mic Bias", ES8328_ADCPOWER, 282 + ES8328_ADCPOWER_MIC_BIAS_OFF, 1, NULL, 0), 283 + SND_SOC_DAPM_SUPPLY("Mic Bias Gen", ES8328_ADCPOWER, 284 + ES8328_ADCPOWER_ADC_BIAS_GEN_OFF, 1, NULL, 0), 285 + 286 + SND_SOC_DAPM_SUPPLY("DAC STM", ES8328_CHIPPOWER, 287 + ES8328_CHIPPOWER_DACSTM_RESET, 1, NULL, 0), 288 + SND_SOC_DAPM_SUPPLY("ADC STM", ES8328_CHIPPOWER, 289 + ES8328_CHIPPOWER_ADCSTM_RESET, 1, NULL, 0), 290 + 291 + SND_SOC_DAPM_SUPPLY("DAC DIG", ES8328_CHIPPOWER, 292 + ES8328_CHIPPOWER_DACDIG_OFF, 1, NULL, 0), 293 + SND_SOC_DAPM_SUPPLY("ADC DIG", ES8328_CHIPPOWER, 294 + ES8328_CHIPPOWER_ADCDIG_OFF, 1, NULL, 0), 295 + 296 + SND_SOC_DAPM_SUPPLY("DAC DLL", ES8328_CHIPPOWER, 297 + ES8328_CHIPPOWER_DACDLL_OFF, 1, NULL, 0), 298 + SND_SOC_DAPM_SUPPLY("ADC DLL", ES8328_CHIPPOWER, 299 + ES8328_CHIPPOWER_ADCDLL_OFF, 1, NULL, 0), 300 + 301 + SND_SOC_DAPM_SUPPLY("ADC Vref", ES8328_CHIPPOWER, 302 + ES8328_CHIPPOWER_ADCVREF_OFF, 1, NULL, 0), 303 + SND_SOC_DAPM_SUPPLY("DAC Vref", ES8328_CHIPPOWER, 304 + ES8328_CHIPPOWER_DACVREF_OFF, 1, NULL, 0), 305 + 306 + SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ES8328_DACPOWER, 307 + ES8328_DACPOWER_RDAC_OFF, 1), 308 + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, 309 + ES8328_DACPOWER_LDAC_OFF, 1), 310 + 311 + SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 312 + &es8328_left_mixer_controls[0], 313 + ARRAY_SIZE(es8328_left_mixer_controls)), 314 + SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, 315 + &es8328_right_mixer_controls[0], 316 + ARRAY_SIZE(es8328_right_mixer_controls)), 317 + 318 + SND_SOC_DAPM_PGA("Right Out 2", ES8328_DACPOWER, 319 + ES8328_DACPOWER_ROUT2_ON, 0, NULL, 0), 320 + SND_SOC_DAPM_PGA("Left Out 2", ES8328_DACPOWER, 321 + ES8328_DACPOWER_LOUT2_ON, 0, NULL, 0), 322 + SND_SOC_DAPM_PGA("Right Out 1", ES8328_DACPOWER, 323 + ES8328_DACPOWER_ROUT1_ON, 0, NULL, 0), 324 + SND_SOC_DAPM_PGA("Left Out 1", ES8328_DACPOWER, 325 + ES8328_DACPOWER_LOUT1_ON, 0, NULL, 0), 326 + 327 + SND_SOC_DAPM_OUTPUT("LOUT1"), 328 + SND_SOC_DAPM_OUTPUT("ROUT1"), 329 + SND_SOC_DAPM_OUTPUT("LOUT2"), 330 + SND_SOC_DAPM_OUTPUT("ROUT2"), 331 + 332 + SND_SOC_DAPM_INPUT("LINPUT1"), 333 + SND_SOC_DAPM_INPUT("LINPUT2"), 334 + SND_SOC_DAPM_INPUT("RINPUT1"), 335 + SND_SOC_DAPM_INPUT("RINPUT2"), 336 + }; 337 + 338 + static const struct snd_soc_dapm_route es8328_dapm_routes[] = { 339 + 340 + { "Left Line Mux", "Line 1", "LINPUT1" }, 341 + { "Left Line Mux", "Line 2", "LINPUT2" }, 342 + { "Left Line Mux", "PGA", "Left PGA Mux" }, 343 + { "Left Line Mux", "Differential", "Differential Mux" }, 344 + 345 + { "Right Line Mux", "Line 1", "RINPUT1" }, 346 + { "Right Line Mux", "Line 2", "RINPUT2" }, 347 + { "Right Line Mux", "PGA", "Right PGA Mux" }, 348 + { "Right Line Mux", "Differential", "Differential Mux" }, 349 + 350 + { "Left PGA Mux", "Line 1", "LINPUT1" }, 351 + { "Left PGA Mux", "Line 2", "LINPUT2" }, 352 + { "Left PGA Mux", "Differential", "Differential Mux" }, 353 + 354 + { "Right PGA Mux", "Line 1", "RINPUT1" }, 355 + { "Right PGA Mux", "Line 2", "RINPUT2" }, 356 + { "Right PGA Mux", "Differential", "Differential Mux" }, 357 + 358 + { "Differential Mux", "Line 1", "LINPUT1" }, 359 + { "Differential Mux", "Line 1", "RINPUT1" }, 360 + { "Differential Mux", "Line 2", "LINPUT2" }, 361 + { "Differential Mux", "Line 2", "RINPUT2" }, 362 + 363 + { "Left ADC Mux", "Stereo", "Left PGA Mux" }, 364 + { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, 365 + { "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, 366 + 367 + { "Right ADC Mux", "Stereo", "Right PGA Mux" }, 368 + { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, 369 + { "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, 370 + 371 + { "Left ADC", NULL, "Left ADC Mux" }, 372 + { "Right ADC", NULL, "Right ADC Mux" }, 373 + 374 + { "ADC DIG", NULL, "ADC STM" }, 375 + { "ADC DIG", NULL, "ADC Vref" }, 376 + { "ADC DIG", NULL, "ADC DLL" }, 377 + 378 + { "Left ADC", NULL, "ADC DIG" }, 379 + { "Right ADC", NULL, "ADC DIG" }, 380 + 381 + { "Mic Bias", NULL, "Mic Bias Gen" }, 382 + 383 + { "Left Line Mux", "Line 1", "LINPUT1" }, 384 + { "Left Line Mux", "Line 2", "LINPUT2" }, 385 + { "Left Line Mux", "PGA", "Left PGA Mux" }, 386 + { "Left Line Mux", "Differential", "Differential Mux" }, 387 + 388 + { "Right Line Mux", "Line 1", "RINPUT1" }, 389 + { "Right Line Mux", "Line 2", "RINPUT2" }, 390 + { "Right Line Mux", "PGA", "Right PGA Mux" }, 391 + { "Right Line Mux", "Differential", "Differential Mux" }, 392 + 393 + { "Left Out 1", NULL, "Left DAC" }, 394 + { "Right Out 1", NULL, "Right DAC" }, 395 + { "Left Out 2", NULL, "Left DAC" }, 396 + { "Right Out 2", NULL, "Right DAC" }, 397 + 398 + { "Left Mixer", "Playback Switch", "Left DAC" }, 399 + { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, 400 + { "Left Mixer", "Right Playback Switch", "Right DAC" }, 401 + { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, 402 + 403 + { "Right Mixer", "Left Playback Switch", "Left DAC" }, 404 + { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, 405 + { "Right Mixer", "Playback Switch", "Right DAC" }, 406 + { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, 407 + 408 + { "DAC DIG", NULL, "DAC STM" }, 409 + { "DAC DIG", NULL, "DAC Vref" }, 410 + { "DAC DIG", NULL, "DAC DLL" }, 411 + 412 + { "Left DAC", NULL, "DAC DIG" }, 413 + { "Right DAC", NULL, "DAC DIG" }, 414 + 415 + { "Left Out 1", NULL, "Left Mixer" }, 416 + { "LOUT1", NULL, "Left Out 1" }, 417 + { "Right Out 1", NULL, "Right Mixer" }, 418 + { "ROUT1", NULL, "Right Out 1" }, 419 + 420 + { "Left Out 2", NULL, "Left Mixer" }, 421 + { "LOUT2", NULL, "Left Out 2" }, 422 + { "Right Out 2", NULL, "Right Mixer" }, 423 + { "ROUT2", NULL, "Right Out 2" }, 424 + }; 425 + 426 + static int es8328_mute(struct snd_soc_dai *dai, int mute) 427 + { 428 + return snd_soc_update_bits(dai->codec, ES8328_DACCONTROL3, 429 + ES8328_DACCONTROL3_DACMUTE, 430 + mute ? ES8328_DACCONTROL3_DACMUTE : 0); 431 + } 432 + 433 + static int es8328_hw_params(struct snd_pcm_substream *substream, 434 + struct snd_pcm_hw_params *params, 435 + struct snd_soc_dai *dai) 436 + { 437 + struct snd_soc_codec *codec = dai->codec; 438 + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 439 + int clk_rate; 440 + int i; 441 + int reg; 442 + u8 ratio; 443 + 444 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 445 + reg = ES8328_DACCONTROL2; 446 + else 447 + reg = ES8328_ADCCONTROL5; 448 + 449 + clk_rate = clk_get_rate(es8328->clk); 450 + 451 + if ((clk_rate != ES8328_SYSCLK_RATE_1X) && 452 + (clk_rate != ES8328_SYSCLK_RATE_2X)) { 453 + dev_err(codec->dev, 454 + "%s: clock is running at %d Hz, not %d or %d Hz\n", 455 + __func__, clk_rate, 456 + ES8328_SYSCLK_RATE_1X, ES8328_SYSCLK_RATE_2X); 457 + return -EINVAL; 458 + } 459 + 460 + /* find master mode MCLK to sampling frequency ratio */ 461 + ratio = mclk_ratios[0].rate; 462 + for (i = 1; i < ARRAY_SIZE(mclk_ratios); i++) 463 + if (params_rate(params) <= mclk_ratios[i].rate) 464 + ratio = mclk_ratios[i].ratio; 465 + 466 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 467 + es8328->playback_fs = params_rate(params); 468 + es8328_set_deemph(codec); 469 + } 470 + 471 + return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio); 472 + } 473 + 474 + static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, 475 + unsigned int fmt) 476 + { 477 + struct snd_soc_codec *codec = codec_dai->codec; 478 + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 479 + int clk_rate; 480 + u8 mode = ES8328_DACCONTROL1_DACWL_16; 481 + 482 + /* set master/slave audio interface */ 483 + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM) 484 + return -EINVAL; 485 + 486 + /* interface format */ 487 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 488 + case SND_SOC_DAIFMT_I2S: 489 + mode |= ES8328_DACCONTROL1_DACFORMAT_I2S; 490 + break; 491 + case SND_SOC_DAIFMT_RIGHT_J: 492 + mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST; 493 + break; 494 + case SND_SOC_DAIFMT_LEFT_J: 495 + mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST; 496 + break; 497 + default: 498 + return -EINVAL; 499 + } 500 + 501 + /* clock inversion */ 502 + if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) 503 + return -EINVAL; 504 + 505 + snd_soc_write(codec, ES8328_DACCONTROL1, mode); 506 + snd_soc_write(codec, ES8328_ADCCONTROL4, mode); 507 + 508 + /* Master serial port mode, with BCLK generated automatically */ 509 + clk_rate = clk_get_rate(es8328->clk); 510 + if (clk_rate == ES8328_SYSCLK_RATE_1X) 511 + snd_soc_write(codec, ES8328_MASTERMODE, 512 + ES8328_MASTERMODE_MSC); 513 + else 514 + snd_soc_write(codec, ES8328_MASTERMODE, 515 + ES8328_MASTERMODE_MCLKDIV2 | 516 + ES8328_MASTERMODE_MSC); 517 + 518 + return 0; 519 + } 520 + 521 + static int es8328_set_bias_level(struct snd_soc_codec *codec, 522 + enum snd_soc_bias_level level) 523 + { 524 + switch (level) { 525 + case SND_SOC_BIAS_ON: 526 + break; 527 + 528 + case SND_SOC_BIAS_PREPARE: 529 + /* VREF, VMID=2x50k, digital enabled */ 530 + snd_soc_write(codec, ES8328_CHIPPOWER, 0); 531 + snd_soc_update_bits(codec, ES8328_CONTROL1, 532 + ES8328_CONTROL1_VMIDSEL_MASK | 533 + ES8328_CONTROL1_ENREF, 534 + ES8328_CONTROL1_VMIDSEL_50k | 535 + ES8328_CONTROL1_ENREF); 536 + break; 537 + 538 + case SND_SOC_BIAS_STANDBY: 539 + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 540 + snd_soc_update_bits(codec, ES8328_CONTROL1, 541 + ES8328_CONTROL1_VMIDSEL_MASK | 542 + ES8328_CONTROL1_ENREF, 543 + ES8328_CONTROL1_VMIDSEL_5k | 544 + ES8328_CONTROL1_ENREF); 545 + 546 + /* Charge caps */ 547 + msleep(100); 548 + } 549 + 550 + snd_soc_write(codec, ES8328_CONTROL2, 551 + ES8328_CONTROL2_OVERCURRENT_ON | 552 + ES8328_CONTROL2_THERMAL_SHUTDOWN_ON); 553 + 554 + /* VREF, VMID=2*500k, digital stopped */ 555 + snd_soc_update_bits(codec, ES8328_CONTROL1, 556 + ES8328_CONTROL1_VMIDSEL_MASK | 557 + ES8328_CONTROL1_ENREF, 558 + ES8328_CONTROL1_VMIDSEL_500k | 559 + ES8328_CONTROL1_ENREF); 560 + break; 561 + 562 + case SND_SOC_BIAS_OFF: 563 + snd_soc_update_bits(codec, ES8328_CONTROL1, 564 + ES8328_CONTROL1_VMIDSEL_MASK | 565 + ES8328_CONTROL1_ENREF, 566 + 0); 567 + break; 568 + } 569 + codec->dapm.bias_level = level; 570 + return 0; 571 + } 572 + 573 + static const struct snd_soc_dai_ops es8328_dai_ops = { 574 + .hw_params = es8328_hw_params, 575 + .digital_mute = es8328_mute, 576 + .set_fmt = es8328_set_dai_fmt, 577 + }; 578 + 579 + static struct snd_soc_dai_driver es8328_dai = { 580 + .name = "es8328-hifi-analog", 581 + .playback = { 582 + .stream_name = "Playback", 583 + .channels_min = 2, 584 + .channels_max = 2, 585 + .rates = ES8328_RATES, 586 + .formats = ES8328_FORMATS, 587 + }, 588 + .capture = { 589 + .stream_name = "Capture", 590 + .channels_min = 2, 591 + .channels_max = 2, 592 + .rates = ES8328_RATES, 593 + .formats = ES8328_FORMATS, 594 + }, 595 + .ops = &es8328_dai_ops, 596 + }; 597 + 598 + static int es8328_suspend(struct snd_soc_codec *codec) 599 + { 600 + struct es8328_priv *es8328; 601 + int ret; 602 + 603 + es8328 = snd_soc_codec_get_drvdata(codec); 604 + 605 + es8328_set_bias_level(codec, SND_SOC_BIAS_OFF); 606 + 607 + clk_disable_unprepare(es8328->clk); 608 + 609 + ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), 610 + es8328->supplies); 611 + if (ret) { 612 + dev_err(codec->dev, "unable to disable regulators\n"); 613 + return ret; 614 + } 615 + return 0; 616 + } 617 + 618 + static int es8328_resume(struct snd_soc_codec *codec) 619 + { 620 + struct regmap *regmap = dev_get_regmap(codec->dev, NULL); 621 + struct es8328_priv *es8328; 622 + int ret; 623 + 624 + es8328 = snd_soc_codec_get_drvdata(codec); 625 + 626 + ret = clk_prepare_enable(es8328->clk); 627 + if (ret) { 628 + dev_err(codec->dev, "unable to enable clock\n"); 629 + return ret; 630 + } 631 + 632 + ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies), 633 + es8328->supplies); 634 + if (ret) { 635 + dev_err(codec->dev, "unable to enable regulators\n"); 636 + return ret; 637 + } 638 + 639 + regcache_mark_dirty(regmap); 640 + ret = regcache_sync(regmap); 641 + if (ret) { 642 + dev_err(codec->dev, "unable to sync regcache\n"); 643 + return ret; 644 + } 645 + 646 + es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 647 + return 0; 648 + } 649 + 650 + static int es8328_codec_probe(struct snd_soc_codec *codec) 651 + { 652 + struct es8328_priv *es8328; 653 + int ret; 654 + 655 + es8328 = snd_soc_codec_get_drvdata(codec); 656 + 657 + ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies), 658 + es8328->supplies); 659 + if (ret) { 660 + dev_err(codec->dev, "unable to enable regulators\n"); 661 + return ret; 662 + } 663 + 664 + /* Setup clocks */ 665 + es8328->clk = devm_clk_get(codec->dev, NULL); 666 + if (IS_ERR(es8328->clk)) { 667 + dev_err(codec->dev, "codec clock missing or invalid\n"); 668 + goto clk_fail; 669 + } 670 + 671 + ret = clk_prepare_enable(es8328->clk); 672 + if (ret) { 673 + dev_err(codec->dev, "unable to prepare codec clk\n"); 674 + goto clk_fail; 675 + } 676 + 677 + return 0; 678 + 679 + clk_fail: 680 + regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), 681 + es8328->supplies); 682 + return ret; 683 + } 684 + 685 + static int es8328_remove(struct snd_soc_codec *codec) 686 + { 687 + struct es8328_priv *es8328; 688 + 689 + es8328 = snd_soc_codec_get_drvdata(codec); 690 + 691 + if (es8328->clk) 692 + clk_disable_unprepare(es8328->clk); 693 + 694 + regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), 695 + es8328->supplies); 696 + 697 + return 0; 698 + } 699 + 700 + const struct regmap_config es8328_regmap_config = { 701 + .reg_bits = 8, 702 + .val_bits = 8, 703 + .max_register = ES8328_REG_MAX, 704 + .cache_type = REGCACHE_RBTREE, 705 + }; 706 + EXPORT_SYMBOL_GPL(es8328_regmap_config); 707 + 708 + static struct snd_soc_codec_driver es8328_codec_driver = { 709 + .probe = es8328_codec_probe, 710 + .suspend = es8328_suspend, 711 + .resume = es8328_resume, 712 + .remove = es8328_remove, 713 + .set_bias_level = es8328_set_bias_level, 714 + .controls = es8328_snd_controls, 715 + .num_controls = ARRAY_SIZE(es8328_snd_controls), 716 + .dapm_widgets = es8328_dapm_widgets, 717 + .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), 718 + .dapm_routes = es8328_dapm_routes, 719 + .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), 720 + }; 721 + 722 + int es8328_probe(struct device *dev, struct regmap *regmap) 723 + { 724 + struct es8328_priv *es8328; 725 + int ret; 726 + int i; 727 + 728 + if (IS_ERR(regmap)) 729 + return PTR_ERR(regmap); 730 + 731 + es8328 = devm_kzalloc(dev, sizeof(*es8328), GFP_KERNEL); 732 + if (es8328 == NULL) 733 + return -ENOMEM; 734 + 735 + es8328->regmap = regmap; 736 + 737 + for (i = 0; i < ARRAY_SIZE(es8328->supplies); i++) 738 + es8328->supplies[i].supply = supply_names[i]; 739 + 740 + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(es8328->supplies), 741 + es8328->supplies); 742 + if (ret) { 743 + dev_err(dev, "unable to get regulators\n"); 744 + return ret; 745 + } 746 + 747 + dev_set_drvdata(dev, es8328); 748 + 749 + return snd_soc_register_codec(dev, 750 + &es8328_codec_driver, &es8328_dai, 1); 751 + } 752 + EXPORT_SYMBOL_GPL(es8328_probe); 753 + 754 + MODULE_DESCRIPTION("ASoC ES8328 driver"); 755 + MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); 756 + MODULE_LICENSE("GPL");
+314
sound/soc/codecs/es8328.h
··· 1 + /* 2 + * es8328.h -- ES8328 ALSA SoC Audio driver 3 + */ 4 + 5 + #ifndef _ES8328_H 6 + #define _ES8328_H 7 + 8 + #include <linux/regmap.h> 9 + 10 + struct device; 11 + 12 + extern const struct regmap_config es8328_regmap_config; 13 + int es8328_probe(struct device *dev, struct regmap *regmap); 14 + 15 + #define ES8328_DACLVOL 46 16 + #define ES8328_DACRVOL 47 17 + #define ES8328_DACCTL 28 18 + #define ES8328_RATEMASK (0x1f << 0) 19 + 20 + #define ES8328_CONTROL1 0x00 21 + #define ES8328_CONTROL1_VMIDSEL_OFF (0 << 0) 22 + #define ES8328_CONTROL1_VMIDSEL_50k (1 << 0) 23 + #define ES8328_CONTROL1_VMIDSEL_500k (2 << 0) 24 + #define ES8328_CONTROL1_VMIDSEL_5k (3 << 0) 25 + #define ES8328_CONTROL1_VMIDSEL_MASK (7 << 0) 26 + #define ES8328_CONTROL1_ENREF (1 << 2) 27 + #define ES8328_CONTROL1_SEQEN (1 << 3) 28 + #define ES8328_CONTROL1_SAMEFS (1 << 4) 29 + #define ES8328_CONTROL1_DACMCLK_ADC (0 << 5) 30 + #define ES8328_CONTROL1_DACMCLK_DAC (1 << 5) 31 + #define ES8328_CONTROL1_LRCM (1 << 6) 32 + #define ES8328_CONTROL1_SCP_RESET (1 << 7) 33 + 34 + #define ES8328_CONTROL2 0x01 35 + #define ES8328_CONTROL2_VREF_BUF_OFF (1 << 0) 36 + #define ES8328_CONTROL2_VREF_LOWPOWER (1 << 1) 37 + #define ES8328_CONTROL2_IBIASGEN_OFF (1 << 2) 38 + #define ES8328_CONTROL2_ANALOG_OFF (1 << 3) 39 + #define ES8328_CONTROL2_VREF_BUF_LOWPOWER (1 << 4) 40 + #define ES8328_CONTROL2_VCM_MOD_LOWPOWER (1 << 5) 41 + #define ES8328_CONTROL2_OVERCURRENT_ON (1 << 6) 42 + #define ES8328_CONTROL2_THERMAL_SHUTDOWN_ON (1 << 7) 43 + 44 + #define ES8328_CHIPPOWER 0x02 45 + #define ES8328_CHIPPOWER_DACVREF_OFF 0 46 + #define ES8328_CHIPPOWER_ADCVREF_OFF 1 47 + #define ES8328_CHIPPOWER_DACDLL_OFF 2 48 + #define ES8328_CHIPPOWER_ADCDLL_OFF 3 49 + #define ES8328_CHIPPOWER_DACSTM_RESET 4 50 + #define ES8328_CHIPPOWER_ADCSTM_RESET 5 51 + #define ES8328_CHIPPOWER_DACDIG_OFF 6 52 + #define ES8328_CHIPPOWER_ADCDIG_OFF 7 53 + 54 + #define ES8328_ADCPOWER 0x03 55 + #define ES8328_ADCPOWER_INT1_LOWPOWER 0 56 + #define ES8328_ADCPOWER_FLASH_ADC_LOWPOWER 1 57 + #define ES8328_ADCPOWER_ADC_BIAS_GEN_OFF 2 58 + #define ES8328_ADCPOWER_MIC_BIAS_OFF 3 59 + #define ES8328_ADCPOWER_ADCR_OFF 4 60 + #define ES8328_ADCPOWER_ADCL_OFF 5 61 + #define ES8328_ADCPOWER_AINR_OFF 6 62 + #define ES8328_ADCPOWER_AINL_OFF 7 63 + 64 + #define ES8328_DACPOWER 0x04 65 + #define ES8328_DACPOWER_OUT3_ON 0 66 + #define ES8328_DACPOWER_MONO_ON 1 67 + #define ES8328_DACPOWER_ROUT2_ON 2 68 + #define ES8328_DACPOWER_LOUT2_ON 3 69 + #define ES8328_DACPOWER_ROUT1_ON 4 70 + #define ES8328_DACPOWER_LOUT1_ON 5 71 + #define ES8328_DACPOWER_RDAC_OFF 6 72 + #define ES8328_DACPOWER_LDAC_OFF 7 73 + 74 + #define ES8328_CHIPLOPOW1 0x05 75 + #define ES8328_CHIPLOPOW2 0x06 76 + #define ES8328_ANAVOLMANAG 0x07 77 + 78 + #define ES8328_MASTERMODE 0x08 79 + #define ES8328_MASTERMODE_BCLKDIV (0 << 0) 80 + #define ES8328_MASTERMODE_BCLK_INV (1 << 5) 81 + #define ES8328_MASTERMODE_MCLKDIV2 (1 << 6) 82 + #define ES8328_MASTERMODE_MSC (1 << 7) 83 + 84 + #define ES8328_ADCCONTROL1 0x09 85 + #define ES8328_ADCCONTROL2 0x0a 86 + #define ES8328_ADCCONTROL3 0x0b 87 + #define ES8328_ADCCONTROL4 0x0c 88 + #define ES8328_ADCCONTROL5 0x0d 89 + #define ES8328_ADCCONTROL5_RATEMASK (0x1f << 0) 90 + 91 + #define ES8328_ADCCONTROL6 0x0e 92 + 93 + #define ES8328_ADCCONTROL7 0x0f 94 + #define ES8328_ADCCONTROL7_ADC_MUTE (1 << 2) 95 + #define ES8328_ADCCONTROL7_ADC_LER (1 << 3) 96 + #define ES8328_ADCCONTROL7_ADC_ZERO_CROSS (1 << 4) 97 + #define ES8328_ADCCONTROL7_ADC_SOFT_RAMP (1 << 5) 98 + #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_4 (0 << 6) 99 + #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_8 (1 << 6) 100 + #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_16 (2 << 6) 101 + #define ES8328_ADCCONTROL7_ADC_RAMP_RATE_32 (3 << 6) 102 + 103 + #define ES8328_ADCCONTROL8 0x10 104 + #define ES8328_ADCCONTROL9 0x11 105 + #define ES8328_ADCCONTROL10 0x12 106 + #define ES8328_ADCCONTROL11 0x13 107 + #define ES8328_ADCCONTROL12 0x14 108 + #define ES8328_ADCCONTROL13 0x15 109 + #define ES8328_ADCCONTROL14 0x16 110 + 111 + #define ES8328_DACCONTROL1 0x17 112 + #define ES8328_DACCONTROL1_DACFORMAT_I2S (0 << 1) 113 + #define ES8328_DACCONTROL1_DACFORMAT_LJUST (1 << 1) 114 + #define ES8328_DACCONTROL1_DACFORMAT_RJUST (2 << 1) 115 + #define ES8328_DACCONTROL1_DACFORMAT_PCM (3 << 1) 116 + #define ES8328_DACCONTROL1_DACWL_24 (0 << 3) 117 + #define ES8328_DACCONTROL1_DACWL_20 (1 << 3) 118 + #define ES8328_DACCONTROL1_DACWL_18 (2 << 3) 119 + #define ES8328_DACCONTROL1_DACWL_16 (3 << 3) 120 + #define ES8328_DACCONTROL1_DACWL_32 (4 << 3) 121 + #define ES8328_DACCONTROL1_DACLRP_I2S_POL_NORMAL (0 << 6) 122 + #define ES8328_DACCONTROL1_DACLRP_I2S_POL_INV (1 << 6) 123 + #define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK2 (0 << 6) 124 + #define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK1 (1 << 6) 125 + #define ES8328_DACCONTROL1_LRSWAP (1 << 7) 126 + 127 + #define ES8328_DACCONTROL2 0x18 128 + #define ES8328_DACCONTROL2_RATEMASK (0x1f << 0) 129 + #define ES8328_DACCONTROL2_DOUBLESPEED (1 << 5) 130 + 131 + #define ES8328_DACCONTROL3 0x19 132 + #define ES8328_DACCONTROL3_AUTOMUTE (1 << 2) 133 + #define ES8328_DACCONTROL3_DACMUTE (1 << 2) 134 + #define ES8328_DACCONTROL3_LEFTGAINVOL (1 << 3) 135 + #define ES8328_DACCONTROL3_DACZEROCROSS (1 << 4) 136 + #define ES8328_DACCONTROL3_DACSOFTRAMP (1 << 5) 137 + #define ES8328_DACCONTROL3_DACRAMPRATE (3 << 6) 138 + 139 + #define ES8328_LDACVOL 0x1a 140 + #define ES8328_LDACVOL_MASK (0 << 0) 141 + #define ES8328_LDACVOL_MAX (0xc0) 142 + 143 + #define ES8328_RDACVOL 0x1b 144 + #define ES8328_RDACVOL_MASK (0 << 0) 145 + #define ES8328_RDACVOL_MAX (0xc0) 146 + 147 + #define ES8328_DACVOL_MAX (0xc0) 148 + 149 + #define ES8328_DACCONTROL4 0x1a 150 + #define ES8328_DACCONTROL5 0x1b 151 + 152 + #define ES8328_DACCONTROL6 0x1c 153 + #define ES8328_DACCONTROL6_CLICKFREE (1 << 3) 154 + #define ES8328_DACCONTROL6_DAC_INVR (1 << 4) 155 + #define ES8328_DACCONTROL6_DAC_INVL (1 << 5) 156 + #define ES8328_DACCONTROL6_DEEMPH_OFF (0 << 6) 157 + #define ES8328_DACCONTROL6_DEEMPH_32k (1 << 6) 158 + #define ES8328_DACCONTROL6_DEEMPH_44_1k (2 << 6) 159 + #define ES8328_DACCONTROL6_DEEMPH_48k (3 << 6) 160 + 161 + #define ES8328_DACCONTROL7 0x1d 162 + #define ES8328_DACCONTROL7_VPP_SCALE_3p5 (0 << 0) 163 + #define ES8328_DACCONTROL7_VPP_SCALE_4p0 (1 << 0) 164 + #define ES8328_DACCONTROL7_VPP_SCALE_3p0 (2 << 0) 165 + #define ES8328_DACCONTROL7_VPP_SCALE_2p5 (3 << 0) 166 + #define ES8328_DACCONTROL7_SHELVING_STRENGTH (1 << 2) /* In eights */ 167 + #define ES8328_DACCONTROL7_MONO (1 << 5) 168 + #define ES8328_DACCONTROL7_ZEROR (1 << 6) 169 + #define ES8328_DACCONTROL7_ZEROL (1 << 7) 170 + 171 + /* Shelving filter */ 172 + #define ES8328_DACCONTROL8 0x1e 173 + #define ES8328_DACCONTROL9 0x1f 174 + #define ES8328_DACCONTROL10 0x20 175 + #define ES8328_DACCONTROL11 0x21 176 + #define ES8328_DACCONTROL12 0x22 177 + #define ES8328_DACCONTROL13 0x23 178 + #define ES8328_DACCONTROL14 0x24 179 + #define ES8328_DACCONTROL15 0x25 180 + 181 + #define ES8328_DACCONTROL16 0x26 182 + #define ES8328_DACCONTROL16_RMIXSEL_RIN1 (0 << 0) 183 + #define ES8328_DACCONTROL16_RMIXSEL_RIN2 (1 << 0) 184 + #define ES8328_DACCONTROL16_RMIXSEL_RIN3 (2 << 0) 185 + #define ES8328_DACCONTROL16_RMIXSEL_RADC (3 << 0) 186 + #define ES8328_DACCONTROL16_LMIXSEL_LIN1 (0 << 3) 187 + #define ES8328_DACCONTROL16_LMIXSEL_LIN2 (1 << 3) 188 + #define ES8328_DACCONTROL16_LMIXSEL_LIN3 (2 << 3) 189 + #define ES8328_DACCONTROL16_LMIXSEL_LADC (3 << 3) 190 + 191 + #define ES8328_DACCONTROL17 0x27 192 + #define ES8328_DACCONTROL17_LI2LOVOL (7 << 3) 193 + #define ES8328_DACCONTROL17_LI2LO (1 << 6) 194 + #define ES8328_DACCONTROL17_LD2LO (1 << 7) 195 + 196 + #define ES8328_DACCONTROL18 0x28 197 + #define ES8328_DACCONTROL18_RI2LOVOL (7 << 3) 198 + #define ES8328_DACCONTROL18_RI2LO (1 << 6) 199 + #define ES8328_DACCONTROL18_RD2LO (1 << 7) 200 + 201 + #define ES8328_DACCONTROL19 0x29 202 + #define ES8328_DACCONTROL19_LI2ROVOL (7 << 3) 203 + #define ES8328_DACCONTROL19_LI2RO (1 << 6) 204 + #define ES8328_DACCONTROL19_LD2RO (1 << 7) 205 + 206 + #define ES8328_DACCONTROL20 0x2a 207 + #define ES8328_DACCONTROL20_RI2ROVOL (7 << 3) 208 + #define ES8328_DACCONTROL20_RI2RO (1 << 6) 209 + #define ES8328_DACCONTROL20_RD2RO (1 << 7) 210 + 211 + #define ES8328_DACCONTROL21 0x2b 212 + #define ES8328_DACCONTROL21_LI2MOVOL (7 << 3) 213 + #define ES8328_DACCONTROL21_LI2MO (1 << 6) 214 + #define ES8328_DACCONTROL21_LD2MO (1 << 7) 215 + 216 + #define ES8328_DACCONTROL22 0x2c 217 + #define ES8328_DACCONTROL22_RI2MOVOL (7 << 3) 218 + #define ES8328_DACCONTROL22_RI2MO (1 << 6) 219 + #define ES8328_DACCONTROL22_RD2MO (1 << 7) 220 + 221 + #define ES8328_DACCONTROL23 0x2d 222 + #define ES8328_DACCONTROL23_MOUTINV (1 << 1) 223 + #define ES8328_DACCONTROL23_HPSWPOL (1 << 2) 224 + #define ES8328_DACCONTROL23_HPSWEN (1 << 3) 225 + #define ES8328_DACCONTROL23_VROI_1p5k (0 << 4) 226 + #define ES8328_DACCONTROL23_VROI_40k (1 << 4) 227 + #define ES8328_DACCONTROL23_OUT3_VREF (0 << 5) 228 + #define ES8328_DACCONTROL23_OUT3_ROUT1 (1 << 5) 229 + #define ES8328_DACCONTROL23_OUT3_MONOOUT (2 << 5) 230 + #define ES8328_DACCONTROL23_OUT3_RIGHT_MIXER (3 << 5) 231 + #define ES8328_DACCONTROL23_ROUT2INV (1 << 7) 232 + 233 + /* LOUT1 Amplifier */ 234 + #define ES8328_LOUT1VOL 0x2e 235 + #define ES8328_LOUT1VOL_MASK (0 << 5) 236 + #define ES8328_LOUT1VOL_MAX (0x24) 237 + 238 + /* ROUT1 Amplifier */ 239 + #define ES8328_ROUT1VOL 0x2f 240 + #define ES8328_ROUT1VOL_MASK (0 << 5) 241 + #define ES8328_ROUT1VOL_MAX (0x24) 242 + 243 + #define ES8328_OUT1VOL_MAX (0x24) 244 + 245 + /* LOUT2 Amplifier */ 246 + #define ES8328_LOUT2VOL 0x30 247 + #define ES8328_LOUT2VOL_MASK (0 << 5) 248 + #define ES8328_LOUT2VOL_MAX (0x24) 249 + 250 + /* ROUT2 Amplifier */ 251 + #define ES8328_ROUT2VOL 0x31 252 + #define ES8328_ROUT2VOL_MASK (0 << 5) 253 + #define ES8328_ROUT2VOL_MAX (0x24) 254 + 255 + #define ES8328_OUT2VOL_MAX (0x24) 256 + 257 + /* Mono Out Amplifier */ 258 + #define ES8328_MONOOUTVOL 0x32 259 + #define ES8328_MONOOUTVOL_MASK (0 << 5) 260 + #define ES8328_MONOOUTVOL_MAX (0x24) 261 + 262 + #define ES8328_DACCONTROL29 0x33 263 + #define ES8328_DACCONTROL30 0x34 264 + 265 + #define ES8328_SYSCLK 0 266 + 267 + #define ES8328_REG_MAX 0x35 268 + 269 + #define ES8328_PLL1 0 270 + #define ES8328_PLL2 1 271 + 272 + /* clock inputs */ 273 + #define ES8328_MCLK 0 274 + #define ES8328_PCMCLK 1 275 + 276 + /* clock divider id's */ 277 + #define ES8328_PCMDIV 0 278 + #define ES8328_BCLKDIV 1 279 + #define ES8328_VXCLKDIV 2 280 + 281 + /* PCM clock dividers */ 282 + #define ES8328_PCM_DIV_1 (0 << 6) 283 + #define ES8328_PCM_DIV_3 (2 << 6) 284 + #define ES8328_PCM_DIV_5_5 (3 << 6) 285 + #define ES8328_PCM_DIV_2 (4 << 6) 286 + #define ES8328_PCM_DIV_4 (5 << 6) 287 + #define ES8328_PCM_DIV_6 (6 << 6) 288 + #define ES8328_PCM_DIV_8 (7 << 6) 289 + 290 + /* BCLK clock dividers */ 291 + #define ES8328_BCLK_DIV_1 (0 << 7) 292 + #define ES8328_BCLK_DIV_2 (1 << 7) 293 + #define ES8328_BCLK_DIV_4 (2 << 7) 294 + #define ES8328_BCLK_DIV_8 (3 << 7) 295 + 296 + /* VXCLK clock dividers */ 297 + #define ES8328_VXCLK_DIV_1 (0 << 6) 298 + #define ES8328_VXCLK_DIV_2 (1 << 6) 299 + #define ES8328_VXCLK_DIV_4 (2 << 6) 300 + #define ES8328_VXCLK_DIV_8 (3 << 6) 301 + #define ES8328_VXCLK_DIV_16 (4 << 6) 302 + 303 + #define ES8328_DAI_HIFI 0 304 + #define ES8328_DAI_VOICE 1 305 + 306 + #define ES8328_1536FS 1536 307 + #define ES8328_1024FS 1024 308 + #define ES8328_768FS 768 309 + #define ES8328_512FS 512 310 + #define ES8328_384FS 384 311 + #define ES8328_256FS 256 312 + #define ES8328_128FS 128 313 + 314 + #endif