iio: adc: aspeed: Use model_data to set clk scaler.

This patch uses need_prescaler and scaler_bit_width to set the ADC clock
scaler.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Link: https://lore.kernel.org/r/20210922081520.30580-5-billy_tsai@aspeedtech.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Billy Tsai 2021-09-22 16:15:13 +08:00 committed by Jonathan Cameron
parent 1de952a4b1
commit 9223bd0471
1 changed files with 26 additions and 15 deletions

View File

@ -210,9 +210,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct aspeed_adc_data *data;
const char *clk_parent_name;
int ret;
u32 adc_engine_control_reg_val;
unsigned long scaler_flags = 0;
char clk_name[32], clk_parent_name[32];
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
if (!indio_dev)
@ -228,24 +229,32 @@ static int aspeed_adc_probe(struct platform_device *pdev)
/* Register ADC clock prescaler with source specified by device tree. */
spin_lock_init(&data->clk_lock);
clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
data->clk_prescaler = clk_hw_register_divider(
&pdev->dev, "prescaler", clk_parent_name, 0,
data->base + ASPEED_REG_CLOCK_CONTROL,
17, 15, 0, &data->clk_lock);
if (IS_ERR(data->clk_prescaler))
return PTR_ERR(data->clk_prescaler);
snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name), "%s",
of_clk_get_parent_name(pdev->dev.of_node, 0));
if (data->model_data->need_prescaler) {
snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-prescaler",
data->model_data->model_name);
data->clk_prescaler = clk_hw_register_divider(
&pdev->dev, clk_name, clk_parent_name, 0,
data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0,
&data->clk_lock);
if (IS_ERR(data->clk_prescaler))
return PTR_ERR(data->clk_prescaler);
snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name),
clk_name);
scaler_flags = CLK_SET_RATE_PARENT;
}
/*
* Register ADC clock scaler downstream from the prescaler. Allow rate
* setting to adjust the prescaler as well.
*/
snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-scaler",
data->model_data->model_name);
data->clk_scaler = clk_hw_register_divider(
&pdev->dev, "scaler", "prescaler",
CLK_SET_RATE_PARENT,
data->base + ASPEED_REG_CLOCK_CONTROL,
0, 10, 0, &data->clk_lock);
&pdev->dev, clk_name, clk_parent_name, scaler_flags,
data->base + ASPEED_REG_CLOCK_CONTROL, 0,
data->model_data->scaler_bit_width, 0, &data->clk_lock);
if (IS_ERR(data->clk_scaler)) {
ret = PTR_ERR(data->clk_scaler);
goto scaler_error;
@ -317,7 +326,8 @@ vref_config_error:
reset_error:
clk_hw_unregister_divider(data->clk_scaler);
scaler_error:
clk_hw_unregister_divider(data->clk_prescaler);
if (data->model_data->need_prescaler)
clk_hw_unregister_divider(data->clk_prescaler);
return ret;
}
@ -332,7 +342,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
clk_disable_unprepare(data->clk_scaler->clk);
reset_control_assert(data->rst);
clk_hw_unregister_divider(data->clk_scaler);
clk_hw_unregister_divider(data->clk_prescaler);
if (data->model_data->need_prescaler)
clk_hw_unregister_divider(data->clk_prescaler);
return 0;
}