1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015 MediaTek Inc.
4 * Author: James Liao <jamesjj.liao@mediatek.com>
7 #include <linux/delay.h>
8 #include <linux/of_address.h>
9 #include <linux/slab.h>
13 #define REF2USB_TX_EN BIT(0)
14 #define REF2USB_TX_LPF_EN BIT(1)
15 #define REF2USB_TX_OUT_EN BIT(2)
16 #define REF2USB_EN_MASK (REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
19 struct mtk_ref2usb_tx
{
21 void __iomem
*base_addr
;
24 static inline struct mtk_ref2usb_tx
*to_mtk_ref2usb_tx(struct clk_hw
*hw
)
26 return container_of(hw
, struct mtk_ref2usb_tx
, hw
);
29 static int mtk_ref2usb_tx_is_prepared(struct clk_hw
*hw
)
31 struct mtk_ref2usb_tx
*tx
= to_mtk_ref2usb_tx(hw
);
33 return (readl(tx
->base_addr
) & REF2USB_EN_MASK
) == REF2USB_EN_MASK
;
36 static int mtk_ref2usb_tx_prepare(struct clk_hw
*hw
)
38 struct mtk_ref2usb_tx
*tx
= to_mtk_ref2usb_tx(hw
);
41 val
= readl(tx
->base_addr
);
44 writel(val
, tx
->base_addr
);
47 val
|= REF2USB_TX_LPF_EN
;
48 writel(val
, tx
->base_addr
);
50 val
|= REF2USB_TX_OUT_EN
;
51 writel(val
, tx
->base_addr
);
56 static void mtk_ref2usb_tx_unprepare(struct clk_hw
*hw
)
58 struct mtk_ref2usb_tx
*tx
= to_mtk_ref2usb_tx(hw
);
61 val
= readl(tx
->base_addr
);
62 val
&= ~REF2USB_EN_MASK
;
63 writel(val
, tx
->base_addr
);
66 static const struct clk_ops mtk_ref2usb_tx_ops
= {
67 .is_prepared
= mtk_ref2usb_tx_is_prepared
,
68 .prepare
= mtk_ref2usb_tx_prepare
,
69 .unprepare
= mtk_ref2usb_tx_unprepare
,
72 struct clk
* __init
mtk_clk_register_ref2usb_tx(const char *name
,
73 const char *parent_name
, void __iomem
*reg
)
75 struct mtk_ref2usb_tx
*tx
;
76 struct clk_init_data init
= {};
79 tx
= kzalloc(sizeof(*tx
), GFP_KERNEL
);
81 return ERR_PTR(-ENOMEM
);
87 init
.ops
= &mtk_ref2usb_tx_ops
;
88 init
.parent_names
= &parent_name
;
91 clk
= clk_register(NULL
, &tx
->hw
);
94 pr_err("Failed to register clk %s: %ld\n", name
, PTR_ERR(clk
));