Lines Matching +full:pclk +full:- +full:sample

1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2015-17 Intel Corporation
5 * skl-ssp-clk.c - ASoC skylake ssp clock driver
12 #include <linux/clk-provider.h>
14 #include <sound/intel-nhlt.h>
16 #include "skl-ssp-clk.h"
17 #include "skl-topology.h"
43 case 0 ... (SKL_SCLK_OFS - 1): in skl_get_clk_type()
46 case SKL_SCLK_OFS ... (SKL_SCLKFS_OFS - 1): in skl_get_clk_type()
49 case SKL_SCLKFS_OFS ... (SKL_MAX_CLK_CNT - 1): in skl_get_clk_type()
53 return -EINVAL; in skl_get_clk_type()
64 return index - SKL_SCLK_OFS; in skl_get_vbus_id()
67 return index - SKL_SCLKFS_OFS; in skl_get_vbus_id()
70 return -EINVAL; in skl_get_vbus_id()
83 ipc = &rcfg->dma_ctl_ipc; in skl_fill_clk_ipc()
85 fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config; in skl_fill_clk_ipc()
86 wfmt = &fmt_cfg->fmt_ext.fmt; in skl_fill_clk_ipc()
89 ipc->sclk_fs.hdr.size = sizeof(struct skl_dmactrl_sclkfs_cfg) - in skl_fill_clk_ipc()
91 ipc->sclk_fs.sampling_frequency = wfmt->samples_per_sec; in skl_fill_clk_ipc()
92 ipc->sclk_fs.bit_depth = wfmt->bits_per_sample; in skl_fill_clk_ipc()
93 ipc->sclk_fs.valid_bit_depth = in skl_fill_clk_ipc()
94 fmt_cfg->fmt_ext.sample.valid_bits_per_sample; in skl_fill_clk_ipc()
95 ipc->sclk_fs.number_of_channels = wfmt->channels; in skl_fill_clk_ipc()
97 ipc->mclk.hdr.type = DMA_CLK_CONTROLS; in skl_fill_clk_ipc()
99 ipc->mclk.hdr.size = sizeof(struct skl_dmactrl_mclk_cfg) - in skl_fill_clk_ipc()
119 return -EIO; in skl_send_clk_dma_control()
121 ipc = &rcfg->dma_ctl_ipc; in skl_send_clk_dma_control()
122 fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config; in skl_send_clk_dma_control()
123 sp_cfg = &fmt_cfg->config; in skl_send_clk_dma_control()
126 ipc->sclk_fs.hdr.type = in skl_send_clk_dma_control()
128 data = (u8 *)&ipc->sclk_fs; in skl_send_clk_dma_control()
133 ipc->mclk.mclk = 0; in skl_send_clk_dma_control()
135 ipc->mclk.mclk = 1; in skl_send_clk_dma_control()
137 ipc->mclk.keep_running = enable; in skl_send_clk_dma_control()
138 ipc->mclk.warm_up_over = enable; in skl_send_clk_dma_control()
139 ipc->mclk.clk_stop_over = !enable; in skl_send_clk_dma_control()
140 data = (u8 *)&ipc->mclk; in skl_send_clk_dma_control()
144 i2s_config_size = sp_cfg->size + size; in skl_send_clk_dma_control()
147 return -ENOMEM; in skl_send_clk_dma_control()
150 memcpy(i2s_config, sp_cfg->caps, sp_cfg->size); in skl_send_clk_dma_control()
153 memcpy(i2s_config + sp_cfg->size, data, size); in skl_send_clk_dma_control()
183 clk_type = skl_get_clk_type(clkdev->id); in skl_clk_change_status()
187 vbus_id = skl_get_vbus_id(clkdev->id, clk_type); in skl_clk_change_status()
191 rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg, in skl_clk_change_status()
192 clkdev->rate); in skl_clk_change_status()
194 return -EINVAL; in skl_clk_change_status()
196 return skl_send_clk_dma_control(clkdev->pdata->pvt_data, rcfg, in skl_clk_change_status()
222 return -EINVAL; in skl_clk_set_rate()
224 rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg, in skl_clk_set_rate()
227 return -EINVAL; in skl_clk_set_rate()
229 clk_type = skl_get_clk_type(clkdev->id); in skl_clk_set_rate()
234 clkdev->rate = rate; in skl_clk_set_rate()
244 if (clkdev->rate) in skl_clk_recalc_rate()
245 return clkdev->rate; in skl_clk_recalc_rate()
259 * in non-atomic context.
269 static void unregister_parent_src_clk(struct skl_clk_parent *pclk, in unregister_parent_src_clk() argument
272 while (id--) { in unregister_parent_src_clk()
273 clkdev_drop(pclk[id].lookup); in unregister_parent_src_clk()
274 clk_hw_unregister_fixed_rate(pclk[id].hw); in unregister_parent_src_clk()
280 while (dclk->avail_clk_cnt--) in unregister_src_clk()
281 clkdev_drop(dclk->clk[dclk->avail_clk_cnt]->lookup); in unregister_src_clk()
286 struct skl_clk_parent_src *pclk) in skl_register_parent_clks() argument
293 parent[i].hw = clk_hw_register_fixed_rate(dev, pclk[i].name, in skl_register_parent_clks()
294 pclk[i].parent_name, 0, pclk[i].rate); in skl_register_parent_clks()
300 parent[i].lookup = clkdev_hw_create(parent[i].hw, pclk[i].name, in skl_register_parent_clks()
304 ret = -ENOMEM; in skl_register_parent_clks()
326 return ERR_PTR(-ENOMEM); in register_skl_clk()
328 init.name = clk->name; in register_skl_clk()
331 init.parent_names = &clk->parent_name; in register_skl_clk()
333 clkdev->hw.init = &init; in register_skl_clk()
334 clkdev->pdata = clk_pdata; in register_skl_clk()
336 clkdev->id = id; in register_skl_clk()
337 ret = devm_clk_hw_register(dev, &clkdev->hw); in register_skl_clk()
343 clkdev->lookup = clkdev_hw_create(&clkdev->hw, init.name, NULL); in register_skl_clk()
344 if (!clkdev->lookup) in register_skl_clk()
345 clkdev = ERR_PTR(-ENOMEM); in register_skl_clk()
352 struct device *dev = &pdev->dev; in skl_clk_dev_probe()
353 struct device *parent_dev = dev->parent; in skl_clk_dev_probe()
360 clk_pdata = dev_get_platdata(&pdev->dev); in skl_clk_dev_probe()
361 parent_clks = clk_pdata->parent_clks; in skl_clk_dev_probe()
362 clks = clk_pdata->ssp_clks; in skl_clk_dev_probe()
364 return -EIO; in skl_clk_dev_probe()
368 return -ENOMEM; in skl_clk_dev_probe()
371 ret = skl_register_parent_clks(parent_dev, data->parent, parent_clks); in skl_clk_dev_probe()
375 for (i = 0; i < clk_pdata->num_clks; i++) { in skl_clk_dev_probe()
383 data->clk[data->avail_clk_cnt] = register_skl_clk(dev, in skl_clk_dev_probe()
386 if (IS_ERR(data->clk[data->avail_clk_cnt])) { in skl_clk_dev_probe()
387 ret = PTR_ERR(data->clk[data->avail_clk_cnt]); in skl_clk_dev_probe()
391 data->avail_clk_cnt++; in skl_clk_dev_probe()
400 unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC); in skl_clk_dev_probe()
411 unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC); in skl_clk_dev_remove()
418 .name = "skl-ssp-clk",
430 MODULE_ALIAS("platform:skl-ssp-clk");