Skip to content

Commit 49393b2

Browse files
AngeloGioacchino Del Regnovinodkoul
authored andcommitted
phy: mediatek: phy-mtk-hdmi: Register PHY provided regulator
At least version 2 of the HDMI PHY, found in MediaTek MT8195 and MT8188 SoCs, does provide hardware support to switch on/off the HDMI 5V pins (which are also used for DDC), and this translates to this being a fixed regulator. Register this PHY-provided regulator so that it can be fed to the hdmi-connector driver to manage the HDMI +5V PWR rail. Signed-off-by: AngeloGioacchino Del Regno <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 2318ca5 commit 49393b2

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/module.h>
1010
#include <linux/phy/phy.h>
1111
#include <linux/platform_device.h>
12+
#include <linux/regulator/driver.h>
13+
#include <linux/regulator/of_regulator.h>
1214
#include <linux/types.h>
1315
#include <linux/units.h>
1416
#include <linux/nvmem-consumer.h>
@@ -478,8 +480,50 @@ static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opt
478480
return ret;
479481
}
480482

483+
static int mtk_hdmi_phy_pwr5v_enable(struct regulator_dev *rdev)
484+
{
485+
struct mtk_hdmi_phy *hdmi_phy = rdev_get_drvdata(rdev);
486+
487+
mtk_phy_set_bits(hdmi_phy->regs + HDMI_CTL_1, RG_HDMITX_PWR5V_O);
488+
489+
return 0;
490+
}
491+
492+
static int mtk_hdmi_phy_pwr5v_disable(struct regulator_dev *rdev)
493+
{
494+
struct mtk_hdmi_phy *hdmi_phy = rdev_get_drvdata(rdev);
495+
496+
mtk_phy_clear_bits(hdmi_phy->regs + HDMI_CTL_1, RG_HDMITX_PWR5V_O);
497+
498+
return 0;
499+
}
500+
501+
static int mtk_hdmi_phy_pwr5v_is_enabled(struct regulator_dev *rdev)
502+
{
503+
struct mtk_hdmi_phy *hdmi_phy = rdev_get_drvdata(rdev);
504+
505+
return !!(readl(hdmi_phy->regs + HDMI_CTL_1) & RG_HDMITX_PWR5V_O);
506+
}
507+
508+
static const struct regulator_ops mtk_hdmi_pwr5v_regulator_ops = {
509+
.enable = mtk_hdmi_phy_pwr5v_enable,
510+
.disable = mtk_hdmi_phy_pwr5v_disable,
511+
.is_enabled = mtk_hdmi_phy_pwr5v_is_enabled
512+
};
513+
514+
static const struct regulator_desc mtk_hdmi_phy_pwr5v_desc = {
515+
.name = "hdmi-pwr5v",
516+
.id = -1,
517+
.n_voltages = 1,
518+
.fixed_uV = 5000000,
519+
.ops = &mtk_hdmi_pwr5v_regulator_ops,
520+
.type = REGULATOR_VOLTAGE,
521+
.owner = THIS_MODULE,
522+
};
523+
481524
struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf = {
482525
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
526+
.hdmi_phy_regulator_desc = &mtk_hdmi_phy_pwr5v_desc,
483527
.hdmi_phy_clk_ops = &mtk_hdmi_pll_ops,
484528
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
485529
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,

drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@
103103
#define HDMI_ANA_CTL 0x7c
104104
#define REG_ANA_HDMI20_FIFO_EN BIT(16)
105105

106+
#define HDMI_CTL_1 0xc4
107+
#define RG_HDMITX_PWR5V_O BIT(9)
108+
106109
#define HDMI_CTL_3 0xcc
107110
#define REG_HDMITXPLL_DIV GENMASK(4, 0)
108111
#define REG_HDMITX_REF_XTAL_SEL BIT(7)

drivers/phy/mediatek/phy-mtk-hdmi.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,28 @@ static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
7575
clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
7676
}
7777

78+
static int mtk_hdmi_phy_register_regulators(struct mtk_hdmi_phy *hdmi_phy)
79+
{
80+
const struct regulator_desc *vreg_desc = hdmi_phy->conf->hdmi_phy_regulator_desc;
81+
const struct regulator_init_data vreg_init_data = {
82+
.constraints = {
83+
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
84+
}
85+
};
86+
struct regulator_config vreg_config = {
87+
.dev = hdmi_phy->dev,
88+
.driver_data = hdmi_phy,
89+
.init_data = &vreg_init_data,
90+
.of_node = hdmi_phy->dev->of_node
91+
};
92+
93+
hdmi_phy->rdev = devm_regulator_register(hdmi_phy->dev, vreg_desc, &vreg_config);
94+
if (IS_ERR(hdmi_phy->rdev))
95+
return PTR_ERR(hdmi_phy->rdev);
96+
97+
return 0;
98+
}
99+
78100
static int mtk_hdmi_phy_probe(struct platform_device *pdev)
79101
{
80102
struct device *dev = &pdev->dev;
@@ -150,6 +172,12 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
150172
if (hdmi_phy->conf->pll_default_off)
151173
hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);
152174

175+
if (hdmi_phy->conf->hdmi_phy_regulator_desc) {
176+
ret = mtk_hdmi_phy_register_regulators(hdmi_phy);
177+
if (ret)
178+
return ret;
179+
}
180+
153181
return of_clk_add_provider(dev->of_node, of_clk_src_simple_get,
154182
hdmi_phy->pll);
155183
}

drivers/phy/mediatek/phy-mtk-hdmi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
#include <linux/module.h>
1414
#include <linux/phy/phy.h>
1515
#include <linux/platform_device.h>
16+
#include <linux/regulator/driver.h>
17+
#include <linux/regulator/machine.h>
1618
#include <linux/types.h>
1719

1820
struct mtk_hdmi_phy;
1921

2022
struct mtk_hdmi_phy_conf {
2123
unsigned long flags;
2224
bool pll_default_off;
25+
const struct regulator_desc *hdmi_phy_regulator_desc;
2326
const struct clk_ops *hdmi_phy_clk_ops;
2427
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
2528
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
@@ -32,6 +35,7 @@ struct mtk_hdmi_phy {
3235
struct mtk_hdmi_phy_conf *conf;
3336
struct clk *pll;
3437
struct clk_hw pll_hw;
38+
struct regulator_dev *rdev;
3539
unsigned long pll_rate;
3640
unsigned char drv_imp_clk;
3741
unsigned char drv_imp_d2;

0 commit comments

Comments
 (0)