Lines Matching +full:reset +full:- +full:source

1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm8804.c -- WM8804 S/PDIF transceiver driver
5 * Copyright 2010-11 Wolfson Microelectronics plc
26 #include <sound/soc-dapm.h>
37 { 3, 0x21 }, /* R3 - PLL1 */
38 { 4, 0xFD }, /* R4 - PLL2 */
39 { 5, 0x36 }, /* R5 - PLL3 */
40 { 6, 0x07 }, /* R6 - PLL4 */
41 { 7, 0x16 }, /* R7 - PLL5 */
42 { 8, 0x18 }, /* R8 - PLL6 */
43 { 9, 0xFF }, /* R9 - SPDMODE */
44 { 10, 0x00 }, /* R10 - INTMASK */
45 { 18, 0x00 }, /* R18 - SPDTX1 */
46 { 19, 0x00 }, /* R19 - SPDTX2 */
47 { 20, 0x00 }, /* R20 - SPDTX3 */
48 { 21, 0x71 }, /* R21 - SPDTX4 */
49 { 22, 0x0B }, /* R22 - SPDTX5 */
50 { 23, 0x70 }, /* R23 - GPO0 */
51 { 24, 0x57 }, /* R24 - GPO1 */
52 { 26, 0x42 }, /* R26 - GPO2 */
53 { 27, 0x06 }, /* R27 - AIFTX */
54 { 28, 0x06 }, /* R28 - AIFRX */
55 { 29, 0x80 }, /* R29 - SPDRX1 */
56 { 30, 0x07 }, /* R30 - PWRDN */
66 struct gpio_desc *reset; member
89 regcache_mark_dirty(wm8804->regmap); \
101 SOC_DAPM_ENUM_EXT("Input Source", txsrc,
112 SND_SOC_DAPM_MUX("Tx Source", SND_SOC_NOPM, 6, 0, wm8804_tx_source_mux),
122 { "Tx Source", "AIF", "AIFRX" },
125 { "Tx Source", "S/PDIF RX", "SPDIFRX" },
127 { "SPDIFTX", NULL, "Tx Source" },
137 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wm8804_aif_event()
143 if (!wm8804->aif_pwr) in wm8804_aif_event()
145 wm8804->aif_pwr++; in wm8804_aif_event()
149 wm8804->aif_pwr--; in wm8804_aif_event()
150 if (!wm8804->aif_pwr) in wm8804_aif_event()
163 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in txsrc_put()
164 unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l; in txsrc_put()
165 unsigned int mask = 1 << e->shift_l; in txsrc_put()
169 return -EINVAL; in txsrc_put()
173 if (snd_soc_component_test_bits(component, e->reg, mask, val)) { in txsrc_put()
180 /* set the tx source */ in txsrc_put()
181 snd_soc_component_update_bits(component, e->reg, mask, val); in txsrc_put()
213 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0); in wm8804_soft_reset()
221 component = dai->component; in wm8804_set_fmt()
238 dev_err(dai->dev, "Unknown dai format\n"); in wm8804_set_fmt()
239 return -EINVAL; in wm8804_set_fmt()
254 dev_err(dai->dev, "Unknown master/slave configuration\n"); in wm8804_set_fmt()
255 return -EINVAL; in wm8804_set_fmt()
275 dev_err(dai->dev, "Unknown polarity configuration\n"); in wm8804_set_fmt()
276 return -EINVAL; in wm8804_set_fmt()
294 component = dai->component; in wm8804_hw_params()
307 dev_err(dai->dev, "Unsupported word length: %u\n", in wm8804_hw_params()
309 return -EINVAL; in wm8804_hw_params()
345 unsigned int source, unsigned int mclk_div) in pll_factors() argument
353 * region of 90-100MHz. in pll_factors()
359 pll_div->freqmode = post_table[i].freqmode; in pll_factors()
360 pll_div->mclkdiv = post_table[i].mclkdiv; in pll_factors()
369 return -EINVAL; in pll_factors()
372 pll_div->prescale = 0; in pll_factors()
373 Ndiv = target / source; in pll_factors()
375 source >>= 1; in pll_factors()
376 pll_div->prescale = 1; in pll_factors()
377 Ndiv = target / source; in pll_factors()
383 return -EINVAL; in pll_factors()
385 pll_div->n = Ndiv; in pll_factors()
387 Nmod = target % source; in pll_factors()
390 do_div(Kpart, source); in pll_factors()
396 pll_div->k = K; in pll_factors()
402 int source, unsigned int freq_in, in wm8804_set_pll() argument
405 struct snd_soc_component *component = dai->component; in wm8804_set_pll()
411 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN, in wm8804_set_pll()
414 pm_runtime_put(wm8804->dev); in wm8804_set_pll()
420 wm8804->mclk_div); in wm8804_set_pll()
425 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN, in wm8804_set_pll()
428 pm_runtime_get_sync(wm8804->dev); in wm8804_set_pll()
453 component = dai->component; in wm8804_set_sysclk()
461 dev_err(dai->dev, "OSCCLOCK is not within the " in wm8804_set_sysclk()
463 return -EINVAL; in wm8804_set_sysclk()
476 dev_err(dai->dev, "Unknown clock source: %d\n", clk_id); in wm8804_set_sysclk()
477 return -EINVAL; in wm8804_set_sysclk()
489 component = dai->component; in wm8804_set_clkdiv()
497 wm8804->mclk_div = div; in wm8804_set_clkdiv()
500 dev_err(dai->dev, "Unknown clock divider: %d\n", div_id); in wm8804_set_clkdiv()
501 return -EINVAL; in wm8804_set_clkdiv()
523 .name = "wm8804-spdif",
573 return -ENOMEM; in wm8804_probe()
577 wm8804->dev = dev; in wm8804_probe()
578 wm8804->regmap = regmap; in wm8804_probe()
580 wm8804->reset = devm_gpiod_get_optional(dev, "wlf,reset", in wm8804_probe()
582 if (IS_ERR(wm8804->reset)) { in wm8804_probe()
583 ret = PTR_ERR(wm8804->reset); in wm8804_probe()
584 dev_err(dev, "Failed to get reset line: %d\n", ret); in wm8804_probe()
588 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) in wm8804_probe()
589 wm8804->supplies[i].supply = wm8804_supply_names[i]; in wm8804_probe()
591 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8804->supplies), in wm8804_probe()
592 wm8804->supplies); in wm8804_probe()
598 wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0; in wm8804_probe()
599 wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1; in wm8804_probe()
602 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) { in wm8804_probe()
603 struct regulator *regulator = wm8804->supplies[i].consumer; in wm8804_probe()
606 &wm8804->disable_nb[i]); in wm8804_probe()
615 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), in wm8804_probe()
616 wm8804->supplies); in wm8804_probe()
622 gpiod_set_value_cansleep(wm8804->reset, 1); in wm8804_probe()
640 ret = -EINVAL; in wm8804_probe()
652 if (!wm8804->reset) { in wm8804_probe()
655 dev_err(dev, "Failed to issue reset: %d\n", ret); in wm8804_probe()
674 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); in wm8804_probe()
691 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), in wm8804_runtime_resume()
692 wm8804->supplies); in wm8804_runtime_resume()
694 dev_err(wm8804->dev, "Failed to enable supplies: %d\n", ret); in wm8804_runtime_resume()
698 regcache_sync(wm8804->regmap); in wm8804_runtime_resume()
701 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x0); in wm8804_runtime_resume()
711 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x8); in wm8804_runtime_suspend()
713 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), in wm8804_runtime_suspend()
714 wm8804->supplies); in wm8804_runtime_suspend()