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

Configure Feed

Select the types of activity you want to include in your feed.

at v5.7-rc2 587 lines 16 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * uda134x.c -- UDA134X ALSA SoC Codec driver 4 * 5 * Modifications by Christian Pellegrin <chripell@evolware.org> 6 * 7 * Copyright 2007 Dension Audio Systems Ltd. 8 * Author: Zoltan Devai 9 * 10 * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie 11 */ 12 13#include <linux/module.h> 14#include <linux/delay.h> 15#include <linux/slab.h> 16#include <sound/pcm.h> 17#include <sound/pcm_params.h> 18#include <sound/soc.h> 19#include <sound/initval.h> 20 21#include <sound/uda134x.h> 22#include <sound/l3.h> 23 24#include "uda134x.h" 25 26 27#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000 28#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ 29 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE) 30 31struct uda134x_priv { 32 int sysclk; 33 int dai_fmt; 34 35 struct snd_pcm_substream *master_substream; 36 struct snd_pcm_substream *slave_substream; 37 38 struct regmap *regmap; 39 struct uda134x_platform_data *pd; 40}; 41 42static const struct reg_default uda134x_reg_defaults[] = { 43 { UDA134X_EA000, 0x04 }, 44 { UDA134X_EA001, 0x04 }, 45 { UDA134X_EA010, 0x04 }, 46 { UDA134X_EA011, 0x00 }, 47 { UDA134X_EA100, 0x00 }, 48 { UDA134X_EA101, 0x00 }, 49 { UDA134X_EA110, 0x00 }, 50 { UDA134X_EA111, 0x00 }, 51 { UDA134X_STATUS0, 0x00 }, 52 { UDA134X_STATUS1, 0x03 }, 53 { UDA134X_DATA000, 0x00 }, 54 { UDA134X_DATA001, 0x00 }, 55 { UDA134X_DATA010, 0x00 }, 56 { UDA134X_DATA011, 0x00 }, 57 { UDA134X_DATA1, 0x00 }, 58}; 59 60/* 61 * Write to the uda134x registers 62 * 63 */ 64static int uda134x_regmap_write(void *context, unsigned int reg, 65 unsigned int value) 66{ 67 struct uda134x_platform_data *pd = context; 68 int ret; 69 u8 addr; 70 u8 data = value; 71 72 switch (reg) { 73 case UDA134X_STATUS0: 74 case UDA134X_STATUS1: 75 addr = UDA134X_STATUS_ADDR; 76 data |= (reg - UDA134X_STATUS0) << 7; 77 break; 78 case UDA134X_DATA000: 79 case UDA134X_DATA001: 80 case UDA134X_DATA010: 81 case UDA134X_DATA011: 82 addr = UDA134X_DATA0_ADDR; 83 data |= (reg - UDA134X_DATA000) << 6; 84 break; 85 case UDA134X_DATA1: 86 addr = UDA134X_DATA1_ADDR; 87 break; 88 default: 89 /* It's an extended address register */ 90 addr = (reg | UDA134X_EXTADDR_PREFIX); 91 92 ret = l3_write(&pd->l3, 93 UDA134X_DATA0_ADDR, &addr, 1); 94 if (ret != 1) 95 return -EIO; 96 97 addr = UDA134X_DATA0_ADDR; 98 data = (value | UDA134X_EXTDATA_PREFIX); 99 break; 100 } 101 102 ret = l3_write(&pd->l3, 103 addr, &data, 1); 104 if (ret != 1) 105 return -EIO; 106 107 return 0; 108} 109 110static inline void uda134x_reset(struct snd_soc_component *component) 111{ 112 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 113 unsigned int mask = 1<<6; 114 115 regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, mask); 116 msleep(1); 117 regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, 0); 118} 119 120static int uda134x_mute(struct snd_soc_dai *dai, int mute) 121{ 122 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(dai->component); 123 unsigned int mask = 1<<2; 124 unsigned int val; 125 126 pr_debug("%s mute: %d\n", __func__, mute); 127 128 if (mute) 129 val = mask; 130 else 131 val = 0; 132 133 return regmap_update_bits(uda134x->regmap, UDA134X_DATA010, mask, val); 134} 135 136static int uda134x_startup(struct snd_pcm_substream *substream, 137 struct snd_soc_dai *dai) 138{ 139 struct snd_soc_component *component = dai->component; 140 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 141 struct snd_pcm_runtime *master_runtime; 142 143 if (uda134x->master_substream) { 144 master_runtime = uda134x->master_substream->runtime; 145 146 pr_debug("%s constraining to %d bits at %d\n", __func__, 147 master_runtime->sample_bits, 148 master_runtime->rate); 149 150 snd_pcm_hw_constraint_single(substream->runtime, 151 SNDRV_PCM_HW_PARAM_RATE, 152 master_runtime->rate); 153 154 snd_pcm_hw_constraint_single(substream->runtime, 155 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 156 master_runtime->sample_bits); 157 158 uda134x->slave_substream = substream; 159 } else 160 uda134x->master_substream = substream; 161 162 return 0; 163} 164 165static void uda134x_shutdown(struct snd_pcm_substream *substream, 166 struct snd_soc_dai *dai) 167{ 168 struct snd_soc_component *component = dai->component; 169 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 170 171 if (uda134x->master_substream == substream) 172 uda134x->master_substream = uda134x->slave_substream; 173 174 uda134x->slave_substream = NULL; 175} 176 177static int uda134x_hw_params(struct snd_pcm_substream *substream, 178 struct snd_pcm_hw_params *params, 179 struct snd_soc_dai *dai) 180{ 181 struct snd_soc_component *component = dai->component; 182 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 183 unsigned int hw_params = 0; 184 185 if (substream == uda134x->slave_substream) { 186 pr_debug("%s ignoring hw_params for slave substream\n", 187 __func__); 188 return 0; 189 } 190 191 pr_debug("%s sysclk: %d, rate:%d\n", __func__, 192 uda134x->sysclk, params_rate(params)); 193 194 /* set SYSCLK / fs ratio */ 195 switch (uda134x->sysclk / params_rate(params)) { 196 case 512: 197 break; 198 case 384: 199 hw_params |= (1<<4); 200 break; 201 case 256: 202 hw_params |= (1<<5); 203 break; 204 default: 205 printk(KERN_ERR "%s unsupported fs\n", __func__); 206 return -EINVAL; 207 } 208 209 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__, 210 uda134x->dai_fmt, params_format(params)); 211 212 /* set DAI format and word length */ 213 switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 214 case SND_SOC_DAIFMT_I2S: 215 break; 216 case SND_SOC_DAIFMT_RIGHT_J: 217 switch (params_width(params)) { 218 case 16: 219 hw_params |= (1<<1); 220 break; 221 case 18: 222 hw_params |= (1<<2); 223 break; 224 case 20: 225 hw_params |= ((1<<2) | (1<<1)); 226 break; 227 default: 228 printk(KERN_ERR "%s unsupported format (right)\n", 229 __func__); 230 return -EINVAL; 231 } 232 break; 233 case SND_SOC_DAIFMT_LEFT_J: 234 hw_params |= (1<<3); 235 break; 236 default: 237 printk(KERN_ERR "%s unsupported format\n", __func__); 238 return -EINVAL; 239 } 240 241 return regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, 242 STATUS0_SYSCLK_MASK | STATUS0_DAIFMT_MASK, hw_params); 243} 244 245static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai, 246 int clk_id, unsigned int freq, int dir) 247{ 248 struct snd_soc_component *component = codec_dai->component; 249 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 250 251 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__, 252 clk_id, freq, dir); 253 254 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable 255 because the codec is slave. Of course limitations of the clock 256 master (the IIS controller) apply. 257 We'll error out on set_hw_params if it's not OK */ 258 if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) { 259 uda134x->sysclk = freq; 260 return 0; 261 } 262 263 printk(KERN_ERR "%s unsupported sysclk\n", __func__); 264 return -EINVAL; 265} 266 267static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai, 268 unsigned int fmt) 269{ 270 struct snd_soc_component *component = codec_dai->component; 271 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 272 273 pr_debug("%s fmt: %08X\n", __func__, fmt); 274 275 /* codec supports only full slave mode */ 276 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { 277 printk(KERN_ERR "%s unsupported slave mode\n", __func__); 278 return -EINVAL; 279 } 280 281 /* no support for clock inversion */ 282 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) { 283 printk(KERN_ERR "%s unsupported clock inversion\n", __func__); 284 return -EINVAL; 285 } 286 287 /* We can't setup DAI format here as it depends on the word bit num */ 288 /* so let's just store the value for later */ 289 uda134x->dai_fmt = fmt; 290 291 return 0; 292} 293 294static int uda134x_set_bias_level(struct snd_soc_component *component, 295 enum snd_soc_bias_level level) 296{ 297 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 298 struct uda134x_platform_data *pd = uda134x->pd; 299 pr_debug("%s bias level %d\n", __func__, level); 300 301 switch (level) { 302 case SND_SOC_BIAS_ON: 303 break; 304 case SND_SOC_BIAS_PREPARE: 305 /* power on */ 306 if (pd->power) { 307 pd->power(1); 308 regcache_sync(uda134x->regmap); 309 } 310 break; 311 case SND_SOC_BIAS_STANDBY: 312 break; 313 case SND_SOC_BIAS_OFF: 314 /* power off */ 315 if (pd->power) { 316 pd->power(0); 317 regcache_mark_dirty(uda134x->regmap); 318 } 319 break; 320 } 321 return 0; 322} 323 324static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1", 325 "Minimum2", "Maximum"}; 326static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 327static const char *uda134x_mixmode[] = {"Differential", "Analog1", 328 "Analog2", "Both"}; 329 330static const struct soc_enum uda134x_mixer_enum[] = { 331SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting), 332SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph), 333SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode), 334}; 335 336static const struct snd_kcontrol_new uda1341_snd_controls[] = { 337SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1), 338SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0), 339SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1), 340SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1), 341 342SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0), 343SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0), 344 345SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0), 346SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0), 347 348SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]), 349SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), 350SOC_ENUM("Input Mux", uda134x_mixer_enum[2]), 351 352SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0), 353SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1), 354SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0), 355 356SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0), 357SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0), 358SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0), 359SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0), 360SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0), 361SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 362}; 363 364static const struct snd_kcontrol_new uda1340_snd_controls[] = { 365SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1), 366 367SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0), 368SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0), 369 370SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]), 371SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), 372 373SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 374}; 375 376static const struct snd_kcontrol_new uda1345_snd_controls[] = { 377SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1), 378 379SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), 380 381SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 382}; 383 384/* UDA1341 has the DAC/ADC power down in STATUS1 */ 385static const struct snd_soc_dapm_widget uda1341_dapm_widgets[] = { 386 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_STATUS1, 0, 0), 387 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_STATUS1, 1, 0), 388}; 389 390/* UDA1340/4/5 has the DAC/ADC pwoer down in DATA0 11 */ 391static const struct snd_soc_dapm_widget uda1340_dapm_widgets[] = { 392 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_DATA011, 0, 0), 393 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_DATA011, 1, 0), 394}; 395 396/* Common DAPM widgets */ 397static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = { 398 SND_SOC_DAPM_INPUT("VINL1"), 399 SND_SOC_DAPM_INPUT("VINR1"), 400 SND_SOC_DAPM_INPUT("VINL2"), 401 SND_SOC_DAPM_INPUT("VINR2"), 402 SND_SOC_DAPM_OUTPUT("VOUTL"), 403 SND_SOC_DAPM_OUTPUT("VOUTR"), 404}; 405 406static const struct snd_soc_dapm_route uda134x_dapm_routes[] = { 407 { "ADC", NULL, "VINL1" }, 408 { "ADC", NULL, "VINR1" }, 409 { "ADC", NULL, "VINL2" }, 410 { "ADC", NULL, "VINR2" }, 411 { "VOUTL", NULL, "DAC" }, 412 { "VOUTR", NULL, "DAC" }, 413}; 414 415static const struct snd_soc_dai_ops uda134x_dai_ops = { 416 .startup = uda134x_startup, 417 .shutdown = uda134x_shutdown, 418 .hw_params = uda134x_hw_params, 419 .digital_mute = uda134x_mute, 420 .set_sysclk = uda134x_set_dai_sysclk, 421 .set_fmt = uda134x_set_dai_fmt, 422}; 423 424static struct snd_soc_dai_driver uda134x_dai = { 425 .name = "uda134x-hifi", 426 /* playback capabilities */ 427 .playback = { 428 .stream_name = "Playback", 429 .channels_min = 1, 430 .channels_max = 2, 431 .rates = UDA134X_RATES, 432 .formats = UDA134X_FORMATS, 433 }, 434 /* capture capabilities */ 435 .capture = { 436 .stream_name = "Capture", 437 .channels_min = 1, 438 .channels_max = 2, 439 .rates = UDA134X_RATES, 440 .formats = UDA134X_FORMATS, 441 }, 442 /* pcm operations */ 443 .ops = &uda134x_dai_ops, 444}; 445 446static int uda134x_soc_probe(struct snd_soc_component *component) 447{ 448 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 449 struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); 450 struct uda134x_platform_data *pd = uda134x->pd; 451 const struct snd_soc_dapm_widget *widgets; 452 unsigned num_widgets; 453 int ret; 454 455 printk(KERN_INFO "UDA134X SoC Audio Codec\n"); 456 457 switch (pd->model) { 458 case UDA134X_UDA1340: 459 case UDA134X_UDA1341: 460 case UDA134X_UDA1344: 461 case UDA134X_UDA1345: 462 break; 463 default: 464 printk(KERN_ERR "UDA134X SoC codec: " 465 "unsupported model %d\n", 466 pd->model); 467 return -EINVAL; 468 } 469 470 if (pd->power) 471 pd->power(1); 472 473 uda134x_reset(component); 474 475 if (pd->model == UDA134X_UDA1341) { 476 widgets = uda1341_dapm_widgets; 477 num_widgets = ARRAY_SIZE(uda1341_dapm_widgets); 478 } else { 479 widgets = uda1340_dapm_widgets; 480 num_widgets = ARRAY_SIZE(uda1340_dapm_widgets); 481 } 482 483 ret = snd_soc_dapm_new_controls(dapm, widgets, num_widgets); 484 if (ret) { 485 printk(KERN_ERR "%s failed to register dapm controls: %d", 486 __func__, ret); 487 return ret; 488 } 489 490 switch (pd->model) { 491 case UDA134X_UDA1340: 492 case UDA134X_UDA1344: 493 ret = snd_soc_add_component_controls(component, uda1340_snd_controls, 494 ARRAY_SIZE(uda1340_snd_controls)); 495 break; 496 case UDA134X_UDA1341: 497 ret = snd_soc_add_component_controls(component, uda1341_snd_controls, 498 ARRAY_SIZE(uda1341_snd_controls)); 499 break; 500 case UDA134X_UDA1345: 501 ret = snd_soc_add_component_controls(component, uda1345_snd_controls, 502 ARRAY_SIZE(uda1345_snd_controls)); 503 break; 504 default: 505 printk(KERN_ERR "%s unknown codec type: %d", 506 __func__, pd->model); 507 return -EINVAL; 508 } 509 510 if (ret < 0) { 511 printk(KERN_ERR "UDA134X: failed to register controls\n"); 512 return ret; 513 } 514 515 return 0; 516} 517 518static const struct snd_soc_component_driver soc_component_dev_uda134x = { 519 .probe = uda134x_soc_probe, 520 .set_bias_level = uda134x_set_bias_level, 521 .dapm_widgets = uda134x_dapm_widgets, 522 .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), 523 .dapm_routes = uda134x_dapm_routes, 524 .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), 525 .suspend_bias_off = 1, 526 .idle_bias_on = 1, 527 .use_pmdown_time = 1, 528 .endianness = 1, 529 .non_legacy_dai_naming = 1, 530}; 531 532static const struct regmap_config uda134x_regmap_config = { 533 .reg_bits = 8, 534 .val_bits = 8, 535 .max_register = UDA134X_DATA1, 536 .reg_defaults = uda134x_reg_defaults, 537 .num_reg_defaults = ARRAY_SIZE(uda134x_reg_defaults), 538 .cache_type = REGCACHE_RBTREE, 539 540 .reg_write = uda134x_regmap_write, 541}; 542 543static int uda134x_codec_probe(struct platform_device *pdev) 544{ 545 struct uda134x_platform_data *pd = pdev->dev.platform_data; 546 struct uda134x_priv *uda134x; 547 int ret; 548 549 if (!pd) { 550 dev_err(&pdev->dev, "Missing L3 bitbang function\n"); 551 return -ENODEV; 552 } 553 554 uda134x = devm_kzalloc(&pdev->dev, sizeof(*uda134x), GFP_KERNEL); 555 if (!uda134x) 556 return -ENOMEM; 557 558 uda134x->pd = pd; 559 platform_set_drvdata(pdev, uda134x); 560 561 if (pd->l3.use_gpios) { 562 ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3); 563 if (ret < 0) 564 return ret; 565 } 566 567 uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, 568 &uda134x_regmap_config); 569 if (IS_ERR(uda134x->regmap)) 570 return PTR_ERR(uda134x->regmap); 571 572 return devm_snd_soc_register_component(&pdev->dev, 573 &soc_component_dev_uda134x, &uda134x_dai, 1); 574} 575 576static struct platform_driver uda134x_codec_driver = { 577 .driver = { 578 .name = "uda134x-codec", 579 }, 580 .probe = uda134x_codec_probe, 581}; 582 583module_platform_driver(uda134x_codec_driver); 584 585MODULE_DESCRIPTION("UDA134X ALSA soc codec driver"); 586MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); 587MODULE_LICENSE("GPL");