1 // SPDX-License-Identifier: GPL-2.0
3 * Freescale SAI BCLK as a generic clock driver
5 * Copyright 2020 Michael Walle <michael@walle.cc>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/clk-provider.h>
11 #include <linux/err.h>
13 #include <linux/of_address.h>
14 #include <linux/slab.h>
18 #define CSR_BCE_BIT 28
19 #define CR2_BCD BIT(24)
20 #define CR2_DIV_SHIFT 0
21 #define CR2_DIV_WIDTH 8
24 struct clk_divider div
;
29 static int fsl_sai_clk_probe(struct platform_device
*pdev
)
31 struct device
*dev
= &pdev
->dev
;
32 struct fsl_sai_clk
*sai_clk
;
33 struct clk_parent_data pdata
= { .index
= 0 };
37 sai_clk
= devm_kzalloc(dev
, sizeof(*sai_clk
), GFP_KERNEL
);
41 base
= devm_platform_ioremap_resource(pdev
, 0);
45 spin_lock_init(&sai_clk
->lock
);
47 sai_clk
->gate
.reg
= base
+ I2S_CSR
;
48 sai_clk
->gate
.bit_idx
= CSR_BCE_BIT
;
49 sai_clk
->gate
.lock
= &sai_clk
->lock
;
51 sai_clk
->div
.reg
= base
+ I2S_CR2
;
52 sai_clk
->div
.shift
= CR2_DIV_SHIFT
;
53 sai_clk
->div
.width
= CR2_DIV_WIDTH
;
54 sai_clk
->div
.lock
= &sai_clk
->lock
;
56 /* set clock direction, we are the BCLK master */
57 writel(CR2_BCD
, base
+ I2S_CR2
);
59 hw
= devm_clk_hw_register_composite_pdata(dev
, dev
->of_node
->name
,
60 &pdata
, 1, NULL
, NULL
,
69 return devm_of_clk_add_hw_provider(dev
, of_clk_hw_simple_get
, hw
);
72 static const struct of_device_id of_fsl_sai_clk_ids
[] = {
73 { .compatible
= "fsl,vf610-sai-clock" },
76 MODULE_DEVICE_TABLE(of
, of_fsl_sai_clk_ids
);
78 static struct platform_driver fsl_sai_clk_driver
= {
79 .probe
= fsl_sai_clk_probe
,
81 .name
= "fsl-sai-clk",
82 .of_match_table
= of_fsl_sai_clk_ids
,
85 module_platform_driver(fsl_sai_clk_driver
);
87 MODULE_DESCRIPTION("Freescale SAI bitclock-as-a-clock driver");
88 MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
89 MODULE_ALIAS("platform:fsl-sai-clk");