1 // SPDX-License-Identifier: GPL-2.0-only
3 * cs4349.c -- CS4349 ALSA Soc Audio driver
5 * Copyright 2015 Cirrus Logic, Inc.
7 * Authors: Tim Howe <Tim.Howe@cirrus.com>
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/delay.h>
15 #include <linux/gpio.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/platform_device.h>
19 #include <linux/i2c.h>
20 #include <linux/of_device.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
23 #include <sound/core.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
26 #include <sound/soc.h>
27 #include <sound/soc-dapm.h>
28 #include <sound/initval.h>
29 #include <sound/tlv.h>
33 static const struct reg_default cs4349_reg_defaults
[] = {
34 { 2, 0x00 }, /* r02 - Mode Control */
35 { 3, 0x09 }, /* r03 - Volume, Mixing and Inversion Control */
36 { 4, 0x81 }, /* r04 - Mute Control */
37 { 5, 0x00 }, /* r05 - Channel A Volume Control */
38 { 6, 0x00 }, /* r06 - Channel B Volume Control */
39 { 7, 0xB1 }, /* r07 - Ramp and Filter Control */
40 { 8, 0x1C }, /* r08 - Misc. Control */
43 /* Private data for the CS4349 */
44 struct cs4349_private
{
45 struct regmap
*regmap
;
46 struct gpio_desc
*reset_gpio
;
51 static bool cs4349_readable_register(struct device
*dev
, unsigned int reg
)
54 case CS4349_CHIPID
... CS4349_MISC
:
61 static bool cs4349_writeable_register(struct device
*dev
, unsigned int reg
)
64 case CS4349_MODE
... CS4349_MISC
:
71 static int cs4349_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
74 struct snd_soc_component
*component
= codec_dai
->component
;
75 struct cs4349_private
*cs4349
= snd_soc_component_get_drvdata(component
);
78 fmt
= format
& SND_SOC_DAIFMT_FORMAT_MASK
;
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
;
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
)
97 struct snd_soc_component
*component
= dai
->component
;
98 struct cs4349_private
*cs4349
= snd_soc_component_get_drvdata(component
);
101 cs4349
->rate
= params_rate(params
);
103 switch (cs4349
->mode
) {
104 case SND_SOC_DAIFMT_I2S
:
107 case SND_SOC_DAIFMT_LEFT_J
:
110 case SND_SOC_DAIFMT_RIGHT_J
:
111 switch (params_width(params
)) {
113 fmt
= DIF_RGHT_JST16
;
116 fmt
= DIF_RGHT_JST24
;
126 ret
= snd_soc_component_update_bits(component
, CS4349_MODE
, DIF_MASK
,
134 static int cs4349_digital_mute(struct snd_soc_dai
*dai
, int mute
)
136 struct snd_soc_component
*component
= dai
->component
;
143 return snd_soc_component_update_bits(component
, CS4349_MUTE
, MUTE_AB_MASK
, reg
);
146 static DECLARE_TLV_DB_SCALE(dig_tlv
, -12750, 50, 0);
148 static const char * const chan_mix_texts
[] = {
149 "Mute", "MuteA", "MuteA SwapB", "MuteA MonoB", "SwapA MuteB",
150 "BothR", "Swap", "SwapA MonoB", "MuteB", "Normal", "BothL",
151 "MonoB", "MonoA MuteB", "MonoA", "MonoA SwapB", "Mono",
152 /*Normal == Channel A = Left, Channel B = Right*/
155 static const char * const fm_texts
[] = {
156 "Auto", "Single", "Double", "Quad",
159 static const char * const deemph_texts
[] = {
160 "None", "44.1k", "48k", "32k",
163 static const char * const softr_zeroc_texts
[] = {
164 "Immediate", "Zero Cross", "Soft Ramp", "SR on ZC",
167 static int deemph_values
[] = {
171 static int softr_zeroc_values
[] = {
175 static const struct soc_enum chan_mix_enum
=
176 SOC_ENUM_SINGLE(CS4349_VMI
, 0,
177 ARRAY_SIZE(chan_mix_texts
),
180 static const struct soc_enum fm_mode_enum
=
181 SOC_ENUM_SINGLE(CS4349_MODE
, 0,
182 ARRAY_SIZE(fm_texts
),
185 static SOC_VALUE_ENUM_SINGLE_DECL(deemph_enum
, CS4349_MODE
, 0, DEM_MASK
,
186 deemph_texts
, deemph_values
);
188 static SOC_VALUE_ENUM_SINGLE_DECL(softr_zeroc_enum
, CS4349_RMPFLT
, 0,
189 SR_ZC_MASK
, softr_zeroc_texts
,
192 static const struct snd_kcontrol_new cs4349_snd_controls
[] = {
193 SOC_DOUBLE_R_TLV("Master Playback Volume",
194 CS4349_VOLA
, CS4349_VOLB
, 0, 0xFF, 1, dig_tlv
),
195 SOC_ENUM("Functional Mode", fm_mode_enum
),
196 SOC_ENUM("De-Emphasis Control", deemph_enum
),
197 SOC_ENUM("Soft Ramp Zero Cross Control", softr_zeroc_enum
),
198 SOC_ENUM("Channel Mixer", chan_mix_enum
),
199 SOC_SINGLE("VolA = VolB Switch", CS4349_VMI
, 7, 1, 0),
200 SOC_SINGLE("InvertA Switch", CS4349_VMI
, 6, 1, 0),
201 SOC_SINGLE("InvertB Switch", CS4349_VMI
, 5, 1, 0),
202 SOC_SINGLE("Auto-Mute Switch", CS4349_MUTE
, 7, 1, 0),
203 SOC_SINGLE("MUTEC A = B Switch", CS4349_MUTE
, 5, 1, 0),
204 SOC_SINGLE("Soft Ramp Up Switch", CS4349_RMPFLT
, 5, 1, 0),
205 SOC_SINGLE("Soft Ramp Down Switch", CS4349_RMPFLT
, 4, 1, 0),
206 SOC_SINGLE("Slow Roll Off Filter Switch", CS4349_RMPFLT
, 2, 1, 0),
207 SOC_SINGLE("Freeze Switch", CS4349_MISC
, 5, 1, 0),
208 SOC_SINGLE("Popguard Switch", CS4349_MISC
, 4, 1, 0),
211 static const struct snd_soc_dapm_widget cs4349_dapm_widgets
[] = {
212 SND_SOC_DAPM_DAC("HiFi DAC", NULL
, SND_SOC_NOPM
, 0, 0),
214 SND_SOC_DAPM_OUTPUT("OutputA"),
215 SND_SOC_DAPM_OUTPUT("OutputB"),
218 static const struct snd_soc_dapm_route cs4349_routes
[] = {
219 {"DAC Playback", NULL
, "OutputA"},
220 {"DAC Playback", NULL
, "OutputB"},
222 {"OutputA", NULL
, "HiFi DAC"},
223 {"OutputB", NULL
, "HiFi DAC"},
226 #define CS4349_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
227 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
228 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
229 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
230 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
231 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
232 SNDRV_PCM_FMTBIT_S32_LE)
234 #define CS4349_PCM_RATES SNDRV_PCM_RATE_8000_192000
236 static const struct snd_soc_dai_ops cs4349_dai_ops
= {
237 .hw_params
= cs4349_pcm_hw_params
,
238 .set_fmt
= cs4349_set_dai_fmt
,
239 .digital_mute
= cs4349_digital_mute
,
242 static struct snd_soc_dai_driver cs4349_dai
= {
243 .name
= "cs4349_hifi",
245 .stream_name
= "DAC Playback",
248 .rates
= CS4349_PCM_RATES
,
249 .formats
= CS4349_PCM_FORMATS
,
251 .ops
= &cs4349_dai_ops
,
252 .symmetric_rates
= 1,
255 static const struct snd_soc_component_driver soc_component_dev_cs4349
= {
256 .controls
= cs4349_snd_controls
,
257 .num_controls
= ARRAY_SIZE(cs4349_snd_controls
),
258 .dapm_widgets
= cs4349_dapm_widgets
,
259 .num_dapm_widgets
= ARRAY_SIZE(cs4349_dapm_widgets
),
260 .dapm_routes
= cs4349_routes
,
261 .num_dapm_routes
= ARRAY_SIZE(cs4349_routes
),
263 .use_pmdown_time
= 1,
265 .non_legacy_dai_naming
= 1,
268 static const struct regmap_config cs4349_regmap
= {
272 .max_register
= CS4349_MISC
,
273 .reg_defaults
= cs4349_reg_defaults
,
274 .num_reg_defaults
= ARRAY_SIZE(cs4349_reg_defaults
),
275 .readable_reg
= cs4349_readable_register
,
276 .writeable_reg
= cs4349_writeable_register
,
277 .cache_type
= REGCACHE_RBTREE
,
280 static int cs4349_i2c_probe(struct i2c_client
*client
,
281 const struct i2c_device_id
*id
)
283 struct cs4349_private
*cs4349
;
286 cs4349
= devm_kzalloc(&client
->dev
, sizeof(*cs4349
), GFP_KERNEL
);
290 cs4349
->regmap
= devm_regmap_init_i2c(client
, &cs4349_regmap
);
291 if (IS_ERR(cs4349
->regmap
)) {
292 ret
= PTR_ERR(cs4349
->regmap
);
293 dev_err(&client
->dev
, "regmap_init() failed: %d\n", ret
);
297 /* Reset the Device */
298 cs4349
->reset_gpio
= devm_gpiod_get_optional(&client
->dev
,
299 "reset", GPIOD_OUT_LOW
);
300 if (IS_ERR(cs4349
->reset_gpio
))
301 return PTR_ERR(cs4349
->reset_gpio
);
303 gpiod_set_value_cansleep(cs4349
->reset_gpio
, 1);
305 i2c_set_clientdata(client
, cs4349
);
307 return devm_snd_soc_register_component(&client
->dev
,
308 &soc_component_dev_cs4349
,
312 static int cs4349_i2c_remove(struct i2c_client
*client
)
314 struct cs4349_private
*cs4349
= i2c_get_clientdata(client
);
316 /* Hold down reset */
317 gpiod_set_value_cansleep(cs4349
->reset_gpio
, 0);
323 static int cs4349_runtime_suspend(struct device
*dev
)
325 struct cs4349_private
*cs4349
= dev_get_drvdata(dev
);
328 ret
= regmap_update_bits(cs4349
->regmap
, CS4349_MISC
, PWR_DWN
, PWR_DWN
);
332 regcache_cache_only(cs4349
->regmap
, true);
334 /* Hold down reset */
335 gpiod_set_value_cansleep(cs4349
->reset_gpio
, 0);
340 static int cs4349_runtime_resume(struct device
*dev
)
342 struct cs4349_private
*cs4349
= dev_get_drvdata(dev
);
345 ret
= regmap_update_bits(cs4349
->regmap
, CS4349_MISC
, PWR_DWN
, 0);
349 gpiod_set_value_cansleep(cs4349
->reset_gpio
, 1);
351 regcache_cache_only(cs4349
->regmap
, false);
352 regcache_sync(cs4349
->regmap
);
358 static const struct dev_pm_ops cs4349_runtime_pm
= {
359 SET_RUNTIME_PM_OPS(cs4349_runtime_suspend
, cs4349_runtime_resume
,
363 static const struct of_device_id cs4349_of_match
[] = {
364 { .compatible
= "cirrus,cs4349", },
368 MODULE_DEVICE_TABLE(of
, cs4349_of_match
);
370 static const struct i2c_device_id cs4349_i2c_id
[] = {
375 MODULE_DEVICE_TABLE(i2c
, cs4349_i2c_id
);
377 static struct i2c_driver cs4349_i2c_driver
= {
380 .of_match_table
= cs4349_of_match
,
381 .pm
= &cs4349_runtime_pm
,
383 .id_table
= cs4349_i2c_id
,
384 .probe
= cs4349_i2c_probe
,
385 .remove
= cs4349_i2c_remove
,
388 module_i2c_driver(cs4349_i2c_driver
);
390 MODULE_AUTHOR("Tim Howe <tim.howe@cirrus.com>");
391 MODULE_DESCRIPTION("Cirrus Logic CS4349 ALSA SoC Codec Driver");
392 MODULE_LICENSE("GPL");