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

ASoC: cs4349: Add support for Cirrus Logic CS4349

Signed-off-by: Tim Howe <tim.howe@cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Tim Howe and committed by
Mark Brown
e40da86a d770e558

+574
+19
Documentation/devicetree/bindings/sound/cs4349.txt
··· 1 + CS4349 audio CODEC 2 + 3 + Required properties: 4 + 5 + - compatible : "cirrus,cs4349" 6 + 7 + - reg : the I2C address of the device for I2C 8 + 9 + Optional properties: 10 + 11 + - reset-gpios : a GPIO spec for the reset pin. 12 + 13 + Example: 14 + 15 + codec: cs4349@48 { 16 + compatible = "cirrus,cs4349"; 17 + reg = <0x48>; 18 + reset-gpios = <&gpio 54 0>; 19 + };
+6
sound/soc/codecs/Kconfig
··· 53 53 select SND_SOC_CS4271_I2C if I2C 54 54 select SND_SOC_CS4271_SPI if SPI_MASTER 55 55 select SND_SOC_CS42XX8_I2C if I2C 56 + select SND_SOC_CS4349 if I2C 56 57 select SND_SOC_CX20442 if TTY 57 58 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 58 59 select SND_SOC_DA7213 if I2C ··· 403 402 depends on I2C 404 403 select SND_SOC_CS42XX8 405 404 select REGMAP_I2C 405 + 406 + # Cirrus Logic CS4349 HiFi DAC 407 + config SND_SOC_CS4349 408 + tristate "Cirrus Logic CS4349 CODEC" 409 + depends on I2C 406 410 407 411 config SND_SOC_CX20442 408 412 tristate
+2
sound/soc/codecs/Makefile
··· 45 45 snd-soc-cs4271-spi-objs := cs4271-spi.o 46 46 snd-soc-cs42xx8-objs := cs42xx8.o 47 47 snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o 48 + snd-soc-cs4349-objs := cs4349.o 48 49 snd-soc-cx20442-objs := cx20442.o 49 50 snd-soc-da7210-objs := da7210.o 50 51 snd-soc-da7213-objs := da7213.o ··· 233 232 obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o 234 233 obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o 235 234 obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o 235 + obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o 236 236 obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 237 237 obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 238 238 obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
+401
sound/soc/codecs/cs4349.c
··· 1 + /* 2 + * cs4349.c -- CS4349 ALSA Soc Audio driver 3 + * 4 + * Copyright 2015 Cirrus Logic, Inc. 5 + * 6 + * Authors: Tim Howe <Tim.Howe@cirrus.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/moduleparam.h> 15 + #include <linux/kernel.h> 16 + #include <linux/init.h> 17 + #include <linux/delay.h> 18 + #include <linux/gpio.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/pm.h> 21 + #include <linux/i2c.h> 22 + #include <linux/of_device.h> 23 + #include <linux/regmap.h> 24 + #include <linux/slab.h> 25 + #include <sound/core.h> 26 + #include <sound/pcm.h> 27 + #include <sound/pcm_params.h> 28 + #include <sound/soc.h> 29 + #include <sound/soc-dapm.h> 30 + #include <sound/initval.h> 31 + #include <sound/tlv.h> 32 + #include "cs4349.h" 33 + 34 + 35 + static const struct reg_default cs4349_reg_defaults[] = { 36 + { 2, 0x00 }, /* r02 - Mode Control */ 37 + { 3, 0x09 }, /* r03 - Volume, Mixing and Inversion Control */ 38 + { 4, 0x81 }, /* r04 - Mute Control */ 39 + { 5, 0x00 }, /* r05 - Channel A Volume Control */ 40 + { 6, 0x00 }, /* r06 - Channel B Volume Control */ 41 + { 7, 0xB1 }, /* r07 - Ramp and Filter Control */ 42 + { 8, 0x1C }, /* r08 - Misc. Control */ 43 + }; 44 + 45 + /* Private data for the CS4349 */ 46 + struct cs4349_private { 47 + struct regmap *regmap; 48 + struct cs4349_platform_data pdata; 49 + struct gpio_desc *reset_gpio; 50 + unsigned int mode; 51 + int rate; 52 + }; 53 + 54 + static bool cs4349_readable_register(struct device *dev, unsigned int reg) 55 + { 56 + switch (reg) { 57 + case CS4349_CHIPID: 58 + case CS4349_MODE: 59 + case CS4349_VMI: 60 + case CS4349_MUTE: 61 + case CS4349_VOLA: 62 + case CS4349_VOLB: 63 + case CS4349_RMPFLT: 64 + case CS4349_MISC: 65 + return true; 66 + default: 67 + return false; 68 + } 69 + } 70 + 71 + static int cs4349_set_dai_fmt(struct snd_soc_dai *codec_dai, 72 + unsigned int format) 73 + { 74 + struct snd_soc_codec *codec = codec_dai->codec; 75 + struct cs4349_private *cs4349 = snd_soc_codec_get_drvdata(codec); 76 + unsigned int fmt; 77 + 78 + fmt = format & SND_SOC_DAIFMT_FORMAT_MASK; 79 + 80 + switch (fmt) { 81 + case SND_SOC_DAIFMT_I2S: 82 + case SND_SOC_DAIFMT_LEFT_J: 83 + case SND_SOC_DAIFMT_RIGHT_J: 84 + cs4349->mode = format & SND_SOC_DAIFMT_FORMAT_MASK; 85 + break; 86 + default: 87 + return -EINVAL; 88 + } 89 + 90 + return 0; 91 + } 92 + 93 + static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream, 94 + struct snd_pcm_hw_params *params, 95 + struct snd_soc_dai *dai) 96 + { 97 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 + struct snd_soc_codec *codec = rtd->codec; 99 + struct cs4349_private *cs4349 = snd_soc_codec_get_drvdata(codec); 100 + int mode, fmt, ret; 101 + 102 + mode = snd_soc_read(codec, CS4349_MODE); 103 + cs4349->rate = params_rate(params); 104 + 105 + switch (cs4349->mode) { 106 + case SND_SOC_DAIFMT_I2S: 107 + mode |= MODE_FORMAT(DIF_I2S); 108 + break; 109 + case SND_SOC_DAIFMT_LEFT_J: 110 + mode |= MODE_FORMAT(DIF_LEFT_JST); 111 + break; 112 + case SND_SOC_DAIFMT_RIGHT_J: 113 + switch (params_width(params)) { 114 + case 16: 115 + fmt = DIF_RGHT_JST16; 116 + break; 117 + case 24: 118 + fmt = DIF_RGHT_JST24; 119 + break; 120 + default: 121 + return -EINVAL; 122 + } 123 + mode |= MODE_FORMAT(fmt); 124 + break; 125 + default: 126 + return -EINVAL; 127 + } 128 + 129 + ret = snd_soc_write(codec, CS4349_MODE, mode); 130 + if (ret < 0) 131 + return ret; 132 + 133 + return 0; 134 + } 135 + 136 + static int cs4349_digital_mute(struct snd_soc_dai *dai, int mute) 137 + { 138 + struct snd_soc_codec *codec = dai->codec; 139 + int reg; 140 + 141 + reg = 0; 142 + if (mute) 143 + reg = MUTE_AB_MASK; 144 + 145 + return snd_soc_update_bits(codec, CS4349_MUTE, MUTE_AB_MASK, reg); 146 + } 147 + 148 + static DECLARE_TLV_DB_SCALE(dig_tlv, -12750, 50, 0); 149 + 150 + static const char * const chan_mix_texts[] = { 151 + "Mute", "MuteA", "MuteA SwapB", "MuteA MonoB", "SwapA MuteB", 152 + "BothR", "Swap", "SwapA MonoB", "MuteB", "Normal", "BothL", 153 + "MonoB", "MonoA MuteB", "MonoA", "MonoA SwapB", "Mono", 154 + /*Normal == Channel A = Left, Channel B = Right*/ 155 + }; 156 + 157 + static const char * const fm_texts[] = { 158 + "Auto", "Single", "Double", "Quad", 159 + }; 160 + 161 + static const char * const deemph_texts[] = { 162 + "None", "44.1k", "48k", "32k", 163 + }; 164 + 165 + static const char * const softr_zeroc_texts[] = { 166 + "Immediate", "Zero Cross", "Soft Ramp", "SR on ZC", 167 + }; 168 + 169 + static int deemph_values[] = { 170 + 0, 4, 8, 12, 171 + }; 172 + 173 + static int softr_zeroc_values[] = { 174 + 0, 64, 128, 192, 175 + }; 176 + 177 + static const struct soc_enum chan_mix_enum = 178 + SOC_ENUM_SINGLE(CS4349_VMI, 0, 179 + ARRAY_SIZE(chan_mix_texts), 180 + chan_mix_texts); 181 + 182 + static const struct soc_enum fm_mode_enum = 183 + SOC_ENUM_SINGLE(CS4349_MODE, 0, 184 + ARRAY_SIZE(fm_texts), 185 + fm_texts); 186 + 187 + static SOC_VALUE_ENUM_SINGLE_DECL(deemph_enum, CS4349_MODE, 0, DEM_MASK, 188 + deemph_texts, deemph_values); 189 + 190 + static SOC_VALUE_ENUM_SINGLE_DECL(softr_zeroc_enum, CS4349_RMPFLT, 0, 191 + SR_ZC_MASK, softr_zeroc_texts, 192 + softr_zeroc_values); 193 + 194 + static const struct snd_kcontrol_new cs4349_snd_controls[] = { 195 + SOC_DOUBLE_R_TLV("Master Playback Volume", 196 + CS4349_VOLA, CS4349_VOLB, 0, 0xFF, 1, dig_tlv), 197 + SOC_ENUM("Functional Mode", fm_mode_enum), 198 + SOC_ENUM("De-Emphasis Control", deemph_enum), 199 + SOC_ENUM("Soft Ramp Zero Cross Control", softr_zeroc_enum), 200 + SOC_ENUM("Channel Mixer", chan_mix_enum), 201 + SOC_SINGLE("VolA = VolB Switch", CS4349_VMI, 7, 1, 0), 202 + SOC_SINGLE("InvertA Switch", CS4349_VMI, 6, 1, 0), 203 + SOC_SINGLE("InvertB Switch", CS4349_VMI, 5, 1, 0), 204 + SOC_SINGLE("Auto-Mute Switch", CS4349_MUTE, 7, 1, 0), 205 + SOC_SINGLE("MUTEC A = B Switch", CS4349_MUTE, 5, 1, 0), 206 + SOC_SINGLE("Soft Ramp Up Switch", CS4349_RMPFLT, 5, 1, 0), 207 + SOC_SINGLE("Soft Ramp Down Switch", CS4349_RMPFLT, 4, 1, 0), 208 + SOC_SINGLE("Slow Roll Off Filter Switch", CS4349_RMPFLT, 2, 1, 0), 209 + SOC_SINGLE("Freeze Switch", CS4349_MISC, 5, 1, 0), 210 + SOC_SINGLE("Popguard Switch", CS4349_MISC, 4, 1, 0), 211 + }; 212 + 213 + static const struct snd_soc_dapm_widget cs4349_dapm_widgets[] = { 214 + SND_SOC_DAPM_DAC("HiFi DAC", NULL, SND_SOC_NOPM, 0, 0), 215 + 216 + SND_SOC_DAPM_OUTPUT("OutputA"), 217 + SND_SOC_DAPM_OUTPUT("OutputB"), 218 + }; 219 + 220 + static const struct snd_soc_dapm_route cs4349_routes[] = { 221 + {"DAC Playback", NULL, "OutputA"}, 222 + {"DAC Playback", NULL, "OutputB"}, 223 + 224 + {"OutputA", NULL, "HiFi DAC"}, 225 + {"OutputB", NULL, "HiFi DAC"}, 226 + }; 227 + 228 + #define CS4349_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 229 + SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ 230 + SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ 231 + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ 232 + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ 233 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ 234 + SNDRV_PCM_FMTBIT_S32_LE) 235 + 236 + #define CS4349_PCM_RATES SNDRV_PCM_RATE_8000_192000 237 + 238 + static const struct snd_soc_dai_ops cs4349_dai_ops = { 239 + .hw_params = cs4349_pcm_hw_params, 240 + .set_fmt = cs4349_set_dai_fmt, 241 + .digital_mute = cs4349_digital_mute, 242 + }; 243 + 244 + static struct snd_soc_dai_driver cs4349_dai = { 245 + .name = "cs4349_hifi", 246 + .playback = { 247 + .stream_name = "DAC Playback", 248 + .channels_min = 1, 249 + .channels_max = 2, 250 + .rates = CS4349_PCM_RATES, 251 + .formats = CS4349_PCM_FORMATS, 252 + }, 253 + .ops = &cs4349_dai_ops, 254 + .symmetric_rates = 1, 255 + }; 256 + 257 + static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { 258 + .controls = cs4349_snd_controls, 259 + .num_controls = ARRAY_SIZE(cs4349_snd_controls), 260 + 261 + .dapm_widgets = cs4349_dapm_widgets, 262 + .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets), 263 + .dapm_routes = cs4349_routes, 264 + .num_dapm_routes = ARRAY_SIZE(cs4349_routes), 265 + }; 266 + 267 + static struct regmap_config cs4349_regmap = { 268 + .reg_bits = 8, 269 + .val_bits = 8, 270 + 271 + .max_register = CS4349_NUMREGS, 272 + .reg_defaults = cs4349_reg_defaults, 273 + .num_reg_defaults = ARRAY_SIZE(cs4349_reg_defaults), 274 + .readable_reg = cs4349_readable_register, 275 + .cache_type = REGCACHE_RBTREE, 276 + }; 277 + 278 + static int cs4349_i2c_probe(struct i2c_client *client, 279 + const struct i2c_device_id *id) 280 + { 281 + struct cs4349_private *cs4349; 282 + struct cs4349_platform_data *pdata = dev_get_platdata(&client->dev); 283 + int ret = 0; 284 + 285 + cs4349 = devm_kzalloc(&client->dev, sizeof(*cs4349), GFP_KERNEL); 286 + if (!cs4349) 287 + return -ENOMEM; 288 + 289 + cs4349->regmap = devm_regmap_init_i2c(client, &cs4349_regmap); 290 + if (IS_ERR(cs4349->regmap)) { 291 + ret = PTR_ERR(cs4349->regmap); 292 + dev_err(&client->dev, "regmap_init() failed: %d\n", ret); 293 + return ret; 294 + } 295 + 296 + if (pdata) 297 + cs4349->pdata = *pdata; 298 + 299 + /* Reset the Device */ 300 + cs4349->reset_gpio = devm_gpiod_get_optional(&client->dev, 301 + "reset", GPIOD_OUT_LOW); 302 + if (IS_ERR(cs4349->reset_gpio)) 303 + return PTR_ERR(cs4349->reset_gpio); 304 + 305 + if (cs4349->reset_gpio) 306 + gpiod_set_value_cansleep(cs4349->reset_gpio, 1); 307 + 308 + i2c_set_clientdata(client, cs4349); 309 + 310 + return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4349, 311 + &cs4349_dai, 1); 312 + } 313 + 314 + static int cs4349_i2c_remove(struct i2c_client *client) 315 + { 316 + struct cs4349_private *cs4349 = i2c_get_clientdata(client); 317 + 318 + snd_soc_unregister_codec(&client->dev); 319 + 320 + /* Hold down reset */ 321 + if (cs4349->reset_gpio) 322 + gpiod_set_value_cansleep(cs4349->reset_gpio, 0); 323 + 324 + return 0; 325 + } 326 + 327 + #ifdef CONFIG_PM 328 + static int cs4349_runtime_suspend(struct device *dev) 329 + { 330 + struct cs4349_private *cs4349 = dev_get_drvdata(dev); 331 + struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); 332 + int ret; 333 + 334 + ret = snd_soc_update_bits(rtd->codec, CS4349_MISC, PWR_DWN, 1); 335 + if (ret < 0) 336 + return ret; 337 + 338 + regcache_cache_only(cs4349->regmap, true); 339 + 340 + /* Hold down reset */ 341 + if (cs4349->reset_gpio) 342 + gpiod_set_value_cansleep(cs4349->reset_gpio, 0); 343 + 344 + return 0; 345 + } 346 + 347 + static int cs4349_runtime_resume(struct device *dev) 348 + { 349 + struct cs4349_private *cs4349 = dev_get_drvdata(dev); 350 + struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); 351 + int ret; 352 + 353 + ret = snd_soc_update_bits(rtd->codec, CS4349_MISC, PWR_DWN, 0); 354 + if (ret < 0) 355 + return ret; 356 + 357 + if (cs4349->reset_gpio) 358 + gpiod_set_value_cansleep(cs4349->reset_gpio, 1); 359 + 360 + regcache_cache_only(cs4349->regmap, false); 361 + regcache_sync(cs4349->regmap); 362 + 363 + return 0; 364 + } 365 + #endif 366 + 367 + static const struct dev_pm_ops cs4349_runtime_pm = { 368 + SET_RUNTIME_PM_OPS(cs4349_runtime_suspend, cs4349_runtime_resume, 369 + NULL) 370 + }; 371 + 372 + static const struct of_device_id cs4349_of_match[] = { 373 + { .compatible = "cirrus,cs4349", }, 374 + {}, 375 + }; 376 + 377 + MODULE_DEVICE_TABLE(of, cs4349_of_match); 378 + 379 + static const struct i2c_device_id cs4349_i2c_id[] = { 380 + {"cs4349", 0}, 381 + {} 382 + }; 383 + 384 + MODULE_DEVICE_TABLE(i2c, cs4349_i2c_id); 385 + 386 + static struct i2c_driver cs4349_i2c_driver = { 387 + .driver = { 388 + .name = "cs4349", 389 + .owner = THIS_MODULE, 390 + .of_match_table = cs4349_of_match, 391 + }, 392 + .id_table = cs4349_i2c_id, 393 + .probe = cs4349_i2c_probe, 394 + .remove = cs4349_i2c_remove, 395 + }; 396 + 397 + module_i2c_driver(cs4349_i2c_driver); 398 + 399 + MODULE_AUTHOR("Tim Howe <tim.howe@cirrus.com>"); 400 + MODULE_DESCRIPTION("Cirrus Logic CS4349 ALSA SoC Codec Driver"); 401 + MODULE_LICENSE("GPL");
+146
sound/soc/codecs/cs4349.h
··· 1 + /* 2 + * ALSA SoC CS4349 codec driver 3 + * 4 + * Copyright 2015 Cirrus Logic, Inc. 5 + * 6 + * Author: Tim Howe <Tim.Howe@cirrus.com> 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, but 13 + * WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 + * General Public License for more details. 16 + * 17 + */ 18 + 19 + #ifndef __CS4349_H__ 20 + #define __CS4349_H__ 21 + 22 + struct cs4349_platform_data { 23 + 24 + /* GPIO for Reset */ 25 + unsigned int gpio_nreset; 26 + 27 + }; 28 + 29 + /* CS4349 registers addresses */ 30 + #define CS4349_CHIPID 0x01 /* Device and Rev ID, Read Only */ 31 + #define CS4349_MODE 0x02 /* Mode Control */ 32 + #define CS4349_VMI 0x03 /* Volume, Mixing, Inversion Control */ 33 + #define CS4349_MUTE 0x04 /* Mute Control */ 34 + #define CS4349_VOLA 0x05 /* DAC Channel A Volume Control */ 35 + #define CS4349_VOLB 0x06 /* DAC Channel B Volume Control */ 36 + #define CS4349_RMPFLT 0x07 /* Ramp and Filter Control */ 37 + #define CS4349_MISC 0x08 /* Power Down,Freeze Control,Pop Stop*/ 38 + 39 + #define CS4349_FIRSTREG 0x01 40 + #define CS4349_LASTREG 0x08 41 + #define CS4349_NUMREGS (CS4349_LASTREG - CS4349_FIRSTREG + 1) 42 + #define CS4349_I2C_INCR 0x80 43 + 44 + 45 + /* Device and Revision ID */ 46 + #define CS4349_REVA 0xF0 /* Rev A */ 47 + #define CS4349_REVB 0xF1 /* Rev B */ 48 + #define CS4349_REVC2 0xFF /* Rev C2 */ 49 + 50 + 51 + /* PDN_DONE Poll Maximum 52 + * If soft ramp is set it will take much longer to power down 53 + * the system. 54 + */ 55 + #define PDN_POLL_MAX 900 56 + 57 + 58 + /* Bitfield Definitions */ 59 + 60 + /* CS4349_MODE */ 61 + /* (Digital Interface Format, De-Emphasis Control, Functional Mode */ 62 + #define DIF2 (1 << 6) 63 + #define DIF1 (1 << 5) 64 + #define DIF0 (1 << 4) 65 + #define DEM1 (1 << 3) 66 + #define DEM0 (1 << 2) 67 + #define FM1 (1 << 1) 68 + #define DIF_LEFT_JST 0x00 69 + #define DIF_I2S 0x01 70 + #define DIF_RGHT_JST16 0x02 71 + #define DIF_RGHT_JST24 0x03 72 + #define DIF_TDM0 0x04 73 + #define DIF_TDM1 0x05 74 + #define DIF_TDM2 0x06 75 + #define DIF_TDM3 0x07 76 + #define DIF_MASK 0x70 77 + #define MODE_FORMAT(x) (((x)&7)<<4) 78 + #define DEM_MASK 0x0C 79 + #define NO_DEM 0x00 80 + #define DEM_441 0x04 81 + #define DEM_48K 0x08 82 + #define DEM_32K 0x0C 83 + #define FM_AUTO 0x00 84 + #define FM_SNGL 0x01 85 + #define FM_DBL 0x02 86 + #define FM_QUAD 0x03 87 + #define FM_SNGL_MIN 30000 88 + #define FM_SNGL_MAX 54000 89 + #define FM_DBL_MAX 108000 90 + #define FM_QUAD_MAX 216000 91 + #define FM_MASK 0x03 92 + 93 + /* CS4349_VMI (VMI = Volume, Mixing and Inversion Controls) */ 94 + #define VOLBISA (1 << 7) 95 + #define VOLAISB (1 << 7) 96 + /* INVERT_A only available for Left Jstfd, Right Jstfd16 and Right Jstfd24 */ 97 + #define INVERT_A (1 << 6) 98 + /* INVERT_B only available for Left Jstfd, Right Jstfd16 and Right Jstfd24 */ 99 + #define INVERT_B (1 << 5) 100 + #define ATAPI3 (1 << 3) 101 + #define ATAPI2 (1 << 2) 102 + #define ATAPI1 (1 << 1) 103 + #define ATAPI0 (1 << 0) 104 + #define MUTEAB 0x00 105 + #define MUTEA_RIGHTB 0x01 106 + #define MUTEA_LEFTB 0x02 107 + #define MUTEA_SUMLRDIV2B 0x03 108 + #define RIGHTA_MUTEB 0x04 109 + #define RIGHTA_RIGHTB 0x05 110 + #define RIGHTA_LEFTB 0x06 111 + #define RIGHTA_SUMLRDIV2B 0x07 112 + #define LEFTA_MUTEB 0x08 113 + #define LEFTA_RIGHTB 0x09 /* Default */ 114 + #define LEFTA_LEFTB 0x0A 115 + #define LEFTA_SUMLRDIV2B 0x0B 116 + #define SUMLRDIV2A_MUTEB 0x0C 117 + #define SUMLRDIV2A_RIGHTB 0x0D 118 + #define SUMLRDIV2A_LEFTB 0x0E 119 + #define SUMLRDIV2_AB 0x0F 120 + #define CHMIX_MASK 0x0F 121 + 122 + /* CS4349_MUTE */ 123 + #define AUTOMUTE (1 << 7) 124 + #define MUTEC_AB (1 << 5) 125 + #define MUTE_A (1 << 4) 126 + #define MUTE_B (1 << 3) 127 + #define MUTE_AB_MASK 0x18 128 + 129 + /* CS4349_RMPFLT (Ramp and Filter Control) */ 130 + #define SCZ1 (1 << 7) 131 + #define SCZ0 (1 << 6) 132 + #define RMP_UP (1 << 5) 133 + #define RMP_DN (1 << 4) 134 + #define FILT_SEL (1 << 2) 135 + #define IMMDT_CHNG 0x31 136 + #define ZEROCRSS 0x71 137 + #define SOFT_RMP 0xB1 138 + #define SFTRMP_ZEROCRSS 0xF1 139 + #define SR_ZC_MASK 0xC0 140 + 141 + /* CS4349_MISC */ 142 + #define PWR_DWN (1 << 7) 143 + #define FREEZE (1 << 5) 144 + #define POPG_EN (1 << 4) 145 + 146 + #endif /* __CS4349_H__ */