2 * Copyright (c) 2015 MediaTek Inc.
3 * Author: James Liao <jamesjj.liao@mediatek.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/delay.h>
16 #include <linux/of_address.h>
17 #include <linux/slab.h>
21 #define REF2USB_TX_EN BIT(0)
22 #define REF2USB_TX_LPF_EN BIT(1)
23 #define REF2USB_TX_OUT_EN BIT(2)
24 #define REF2USB_EN_MASK (REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
27 struct mtk_ref2usb_tx
{
29 void __iomem
*base_addr
;
32 static inline struct mtk_ref2usb_tx
*to_mtk_ref2usb_tx(struct clk_hw
*hw
)
34 return container_of(hw
, struct mtk_ref2usb_tx
, hw
);
37 static int mtk_ref2usb_tx_is_prepared(struct clk_hw
*hw
)
39 struct mtk_ref2usb_tx
*tx
= to_mtk_ref2usb_tx(hw
);
41 return (readl(tx
->base_addr
) & REF2USB_EN_MASK
) == REF2USB_EN_MASK
;
44 static int mtk_ref2usb_tx_prepare(struct clk_hw
*hw
)
46 struct mtk_ref2usb_tx
*tx
= to_mtk_ref2usb_tx(hw
);
49 val
= readl(tx
->base_addr
);
52 writel(val
, tx
->base_addr
);
55 val
|= REF2USB_TX_LPF_EN
;
56 writel(val
, tx
->base_addr
);
58 val
|= REF2USB_TX_OUT_EN
;
59 writel(val
, tx
->base_addr
);
64 static void mtk_ref2usb_tx_unprepare(struct clk_hw
*hw
)
66 struct mtk_ref2usb_tx
*tx
= to_mtk_ref2usb_tx(hw
);
69 val
= readl(tx
->base_addr
);
70 val
&= ~REF2USB_EN_MASK
;
71 writel(val
, tx
->base_addr
);
74 static const struct clk_ops mtk_ref2usb_tx_ops
= {
75 .is_prepared
= mtk_ref2usb_tx_is_prepared
,
76 .prepare
= mtk_ref2usb_tx_prepare
,
77 .unprepare
= mtk_ref2usb_tx_unprepare
,
80 struct clk
* __init
mtk_clk_register_ref2usb_tx(const char *name
,
81 const char *parent_name
, void __iomem
*reg
)
83 struct mtk_ref2usb_tx
*tx
;
84 struct clk_init_data init
= {};
87 tx
= kzalloc(sizeof(*tx
), GFP_KERNEL
);
89 return ERR_PTR(-ENOMEM
);
95 init
.ops
= &mtk_ref2usb_tx_ops
;
96 init
.parent_names
= &parent_name
;
99 clk
= clk_register(NULL
, &tx
->hw
);
102 pr_err("Failed to register clk %s: %ld\n", name
, PTR_ERR(clk
));