Lines Matching +full:ep9301 +full:- +full:adc
1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Based on a rewrite of arch/arm/mach-ep93xx/clock.c:
13 #include <linux/clk-provider.h>
20 #include <dt-bindings/clock/cirrus,ep9301-syscon.h>
105 return container_of(clk, struct ep93xx_clk_priv, reg[clk->idx]); in ep93xx_priv_from()
110 struct ep93xx_regmap_adev *aux = priv->aux_dev; in ep93xx_clk_write()
112 aux->write(aux->map, aux->lock, reg, val); in ep93xx_clk_write()
121 regmap_read(priv->map, clk->reg, &val); in ep93xx_clk_is_enabled()
123 return !!(val & BIT(clk->bit_idx)); in ep93xx_clk_is_enabled()
132 guard(spinlock_irqsave)(&priv->lock); in ep93xx_clk_enable()
134 regmap_read(priv->map, clk->reg, &val); in ep93xx_clk_enable()
135 val |= BIT(clk->bit_idx); in ep93xx_clk_enable()
137 ep93xx_clk_write(priv, clk->reg, val); in ep93xx_clk_enable()
148 guard(spinlock_irqsave)(&priv->lock); in ep93xx_clk_disable()
150 regmap_read(priv->map, clk->reg, &val); in ep93xx_clk_disable()
151 val &= ~BIT(clk->bit_idx); in ep93xx_clk_disable()
153 ep93xx_clk_write(priv, clk->reg, val); in ep93xx_clk_disable()
178 clk->reg = reg; in ep93xx_clk_register_gate()
179 clk->bit_idx = bit_idx; in ep93xx_clk_register_gate()
180 clk->hw.init = &init; in ep93xx_clk_register_gate()
182 return devm_clk_hw_register(priv->dev, &clk->hw); in ep93xx_clk_register_gate()
191 regmap_read(priv->map, clk->reg, &val); in ep93xx_mux_get_parent()
212 return -EINVAL; in ep93xx_mux_set_parent_lock()
214 guard(spinlock_irqsave)(&priv->lock); in ep93xx_mux_set_parent_lock()
216 regmap_read(priv->map, clk->reg, &val); in ep93xx_mux_set_parent_lock()
221 ep93xx_clk_write(priv, clk->reg, val); in ep93xx_mux_set_parent_lock()
236 unsigned long rate = req->rate; in ep93xx_mux_determine_rate()
249 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf in ep93xx_mux_determine_rate()
274 return -EINVAL; in ep93xx_mux_determine_rate()
276 req->best_parent_rate = parent_rate_best; in ep93xx_mux_determine_rate()
277 req->best_parent_hw = parent_best; in ep93xx_mux_determine_rate()
278 req->rate = best_rate; in ep93xx_mux_determine_rate()
291 regmap_read(priv->map, clk->reg, &val); in ep93xx_ddiv_recalc_rate()
309 regmap_read(priv->map, clk->reg, &val); in ep93xx_ddiv_set_rate()
318 if (abs(actual_rate - rate) < rate_err) { in ep93xx_ddiv_set_rate()
319 npdiv = pdiv - 3; in ep93xx_ddiv_set_rate()
321 rate_err = abs(actual_rate - rate); in ep93xx_ddiv_set_rate()
326 return -EINVAL; in ep93xx_ddiv_set_rate()
337 ep93xx_clk_write(priv, clk->reg, val); in ep93xx_ddiv_set_rate()
369 clk->reg = reg; in ep93xx_clk_register_ddiv()
370 clk->bit_idx = bit_idx; in ep93xx_clk_register_ddiv()
371 clk->hw.init = &init; in ep93xx_clk_register_ddiv()
373 return devm_clk_hw_register(priv->dev, &clk->hw); in ep93xx_clk_register_ddiv()
384 regmap_read(priv->map, clk->reg, &val); in ep93xx_div_recalc_rate()
385 index = (val & clk->mask) >> clk->shift; in ep93xx_div_recalc_rate()
386 if (index >= clk->num_div) in ep93xx_div_recalc_rate()
389 return DIV_ROUND_CLOSEST(parent_rate, clk->div[index]); in ep93xx_div_recalc_rate()
399 for (i = 0; i < clk->num_div; i++) { in ep93xx_div_round_rate()
400 if ((rate * clk->div[i]) == *parent_rate) in ep93xx_div_round_rate()
403 now = DIV_ROUND_CLOSEST(*parent_rate, clk->div[i]); in ep93xx_div_round_rate()
419 regmap_read(priv->map, clk->reg, &val); in ep93xx_div_set_rate()
420 val &= ~clk->mask; in ep93xx_div_set_rate()
421 for (i = 0; i < clk->num_div; i++) in ep93xx_div_set_rate()
422 if (rate == DIV_ROUND_CLOSEST(parent_rate, clk->div[i])) in ep93xx_div_set_rate()
425 if (i == clk->num_div) in ep93xx_div_set_rate()
426 return -EINVAL; in ep93xx_div_set_rate()
428 val |= i << clk->shift; in ep93xx_div_set_rate()
430 ep93xx_clk_write(priv, clk->reg, val); in ep93xx_div_set_rate()
463 clk->reg = reg; in ep93xx_register_div()
464 clk->bit_idx = enable_bit; in ep93xx_register_div()
465 clk->mask = GENMASK(shift + width - 1, shift); in ep93xx_register_div()
466 clk->shift = shift; in ep93xx_register_div()
467 clk->div = clk_divisors; in ep93xx_register_div()
468 clk->num_div = num_div; in ep93xx_register_div()
469 clk->hw.init = &init; in ep93xx_register_div()
471 return devm_clk_hw_register(priv->dev, &clk->hw); in ep93xx_register_div()
493 regmap_read(priv->map, EP93XX_SYSCON_PWRCNT, &val); in ep93xx_uart_clock_init()
499 priv->fixed[EP93XX_CLK_UART] = in ep93xx_uart_clock_init()
500 devm_clk_hw_register_fixed_factor_index(priv->dev, "uart", in ep93xx_uart_clock_init()
503 parent_data.hw = priv->fixed[EP93XX_CLK_UART]; in ep93xx_uart_clock_init()
507 idx = ep93xx_uarts[i].idx - EP93XX_CLK_UART1; in ep93xx_uart_clock_init()
508 clk = &priv->reg[idx]; in ep93xx_uart_clock_init()
509 clk->idx = idx; in ep93xx_uart_clock_init()
516 return dev_err_probe(priv->dev, ret, in ep93xx_uart_clock_init()
543 parent_data.hw = priv->fixed[EP93XX_CLK_HCLK]; in ep93xx_dma_clock_init()
546 priv->fixed[idx] = devm_clk_hw_register_gate_parent_data(priv->dev, in ep93xx_dma_clock_init()
549 priv->base + EP93XX_SYSCON_PWRCNT, in ep93xx_dma_clock_init()
552 &priv->lock); in ep93xx_dma_clock_init()
553 if (IS_ERR(priv->fixed[idx])) in ep93xx_dma_clock_init()
554 return PTR_ERR(priv->fixed[idx]); in ep93xx_dma_clock_init()
563 unsigned int idx = clkspec->args[0]; in of_clk_ep93xx_get()
566 return priv->fixed[idx]; in of_clk_ep93xx_get()
569 return &priv->reg[idx - EP93XX_CLK_UART1].hw; in of_clk_ep93xx_get()
571 return ERR_PTR(-EINVAL); in of_clk_ep93xx_get()
595 struct device *dev = priv->dev; in ep93xx_plls_init()
600 regmap_read(priv->map, EP93XX_SYSCON_CLKSET1, &value); in ep93xx_plls_init()
612 priv->fixed[EP93XX_CLK_PLL1] = pll1; in ep93xx_plls_init()
623 priv->fixed[EP93XX_CLK_FCLK] = hw; in ep93xx_plls_init()
629 priv->fixed[EP93XX_CLK_HCLK] = hw; in ep93xx_plls_init()
635 priv->fixed[EP93XX_CLK_PCLK] = hw; in ep93xx_plls_init()
638 regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value); in ep93xx_plls_init()
651 priv->fixed[EP93XX_CLK_PLL2] = hw; in ep93xx_plls_init()
664 struct device *dev = &adev->dev; in ep93xx_clk_probe()
674 return -ENOMEM; in ep93xx_clk_probe()
676 spin_lock_init(&priv->lock); in ep93xx_clk_probe()
677 priv->dev = dev; in ep93xx_clk_probe()
678 priv->aux_dev = rdev; in ep93xx_clk_probe()
679 priv->map = rdev->map; in ep93xx_clk_probe()
680 priv->base = rdev->base; in ep93xx_clk_probe()
686 regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value); in ep93xx_clk_probe()
689 priv->fixed[EP93XX_CLK_PLL2], 0, 1, in ep93xx_clk_probe()
694 priv->fixed[EP93XX_CLK_USB] = hw; in ep93xx_clk_probe()
704 clk_spi_div = id->driver_data; in ep93xx_clk_probe()
705 hw = devm_clk_hw_register_fixed_factor_index(dev, "ep93xx-spi.0", in ep93xx_clk_probe()
711 priv->fixed[EP93XX_CLK_SPI] = hw; in ep93xx_clk_probe()
719 priv->fixed[EP93XX_CLK_PWM] = hw; in ep93xx_clk_probe()
722 pdata.hw = priv->fixed[EP93XX_CLK_USB]; in ep93xx_clk_probe()
723 hw = devm_clk_hw_register_gate_parent_data(priv->dev, "ohci-platform", &pdata, in ep93xx_clk_probe()
724 0, priv->base + EP93XX_SYSCON_PWRCNT, in ep93xx_clk_probe()
726 &priv->lock); in ep93xx_clk_probe()
730 priv->fixed[EP93XX_CLK_USB] = hw; in ep93xx_clk_probe()
733 ddiv_pdata[1].hw = priv->fixed[EP93XX_CLK_PLL1]; in ep93xx_clk_probe()
734 ddiv_pdata[2].hw = priv->fixed[EP93XX_CLK_PLL2]; in ep93xx_clk_probe()
736 /* touchscreen/ADC clock */ in ep93xx_clk_probe()
737 idx = EP93XX_CLK_ADC - EP93XX_CLK_UART1; in ep93xx_clk_probe()
738 clk = &priv->reg[idx]; in ep93xx_clk_probe()
739 clk->idx = idx; in ep93xx_clk_probe()
740 ret = ep93xx_register_div(clk, "ep93xx-adc", &xtali, in ep93xx_clk_probe()
750 idx = EP93XX_CLK_KEYPAD - EP93XX_CLK_UART1; in ep93xx_clk_probe()
751 clk = &priv->reg[idx]; in ep93xx_clk_probe()
752 clk->idx = idx; in ep93xx_clk_probe()
753 ret = ep93xx_register_div(clk, "ep93xx-keypad", &xtali, in ep93xx_clk_probe()
765 * ENA - Enable CLK divider. in ep93xx_clk_probe()
766 * PDIV - 00 - Disable clock in ep93xx_clk_probe()
767 * VDIV - at least 2 in ep93xx_clk_probe()
771 regmap_read(priv->map, EP93XX_SYSCON_VIDCLKDIV, &value); in ep93xx_clk_probe()
776 regmap_read(priv->map, EP93XX_SYSCON_I2SCLKDIV, &value); in ep93xx_clk_probe()
788 idx = EP93XX_CLK_VIDEO - EP93XX_CLK_UART1; in ep93xx_clk_probe()
789 clk = &priv->reg[idx]; in ep93xx_clk_probe()
790 clk->idx = idx; in ep93xx_clk_probe()
791 ret = ep93xx_clk_register_ddiv(clk, "ep93xx-fb", in ep93xx_clk_probe()
797 idx = EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1; in ep93xx_clk_probe()
798 clk = &priv->reg[idx]; in ep93xx_clk_probe()
799 clk->idx = idx; in ep93xx_clk_probe()
806 idx = EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1; in ep93xx_clk_probe()
807 clk = &priv->reg[idx]; in ep93xx_clk_probe()
808 clk->idx = idx; in ep93xx_clk_probe()
809 pdata.hw = &priv->reg[EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1].hw; in ep93xx_clk_probe()
819 idx = EP93XX_CLK_I2S_LRCLK - EP93XX_CLK_UART1; in ep93xx_clk_probe()
820 clk = &priv->reg[idx]; in ep93xx_clk_probe()
821 clk->idx = idx; in ep93xx_clk_probe()
822 pdata.hw = &priv->reg[EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1].hw; in ep93xx_clk_probe()
832 return devm_of_clk_add_hw_provider(priv->dev, of_clk_ep93xx_get, priv); in ep93xx_clk_probe()
836 { .name = "soc_ep93xx.clk-ep93xx", .driver_data = 2, },
837 { .name = "soc_ep93xx.clk-ep93xx.e2", .driver_data = 1, },