2 * Copyright (C) 2013 Red Hat
3 * Author: Rob Clark <robdclark@gmail.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
20 static struct platform_device
*hdmi_pdev
;
22 void hdmi_set_mode(struct hdmi
*hdmi
, bool power_on
)
27 ctrl
|= HDMI_CTRL_ENABLE
;
28 if (!hdmi
->hdmi_mode
) {
29 ctrl
|= HDMI_CTRL_HDMI
;
30 hdmi_write(hdmi
, REG_HDMI_CTRL
, ctrl
);
31 ctrl
&= ~HDMI_CTRL_HDMI
;
33 ctrl
|= HDMI_CTRL_HDMI
;
36 ctrl
= HDMI_CTRL_HDMI
;
39 hdmi_write(hdmi
, REG_HDMI_CTRL
, ctrl
);
40 DBG("HDMI Core: %s, HDMI_CTRL=0x%08x",
41 power_on
? "Enable" : "Disable", ctrl
);
44 static irqreturn_t
hdmi_irq(int irq
, void *dev_id
)
46 struct hdmi
*hdmi
= dev_id
;
49 hdmi_connector_irq(hdmi
->connector
);
52 hdmi_i2c_irq(hdmi
->i2c
);
59 void hdmi_destroy(struct hdmi
*hdmi
)
61 struct hdmi_phy
*phy
= hdmi
->phy
;
64 phy
->funcs
->destroy(phy
);
67 hdmi_i2c_destroy(hdmi
->i2c
);
69 put_device(&hdmi
->pdev
->dev
);
72 /* initialize connector */
73 int hdmi_init(struct hdmi
*hdmi
, struct drm_device
*dev
,
74 struct drm_connector
*connector
)
76 struct platform_device
*pdev
= hdmi_pdev
;
77 struct hdmi_platform_config
*config
;
81 dev_err(dev
->dev
, "no hdmi device\n");
86 config
= pdev
->dev
.platform_data
;
88 get_device(&pdev
->dev
);
92 hdmi
->connector
= connector
;
94 /* not sure about which phy maps to which msm.. probably I miss some */
96 hdmi
->phy
= config
->phy_init(hdmi
);
98 hdmi
->phy
= ERR_PTR(-ENXIO
);
100 if (IS_ERR(hdmi
->phy
)) {
101 ret
= PTR_ERR(hdmi
->phy
);
102 dev_err(dev
->dev
, "failed to load phy: %d\n", ret
);
107 hdmi
->mmio
= msm_ioremap(pdev
, "hdmi_msm_hdmi_addr", "HDMI");
108 if (IS_ERR(hdmi
->mmio
)) {
109 ret
= PTR_ERR(hdmi
->mmio
);
113 hdmi
->mvs
= devm_regulator_get(&pdev
->dev
, "8901_hdmi_mvs");
114 if (IS_ERR(hdmi
->mvs
))
115 hdmi
->mvs
= devm_regulator_get(&pdev
->dev
, "hdmi_mvs");
116 if (IS_ERR(hdmi
->mvs
)) {
117 ret
= PTR_ERR(hdmi
->mvs
);
118 dev_err(dev
->dev
, "failed to get mvs regulator: %d\n", ret
);
122 hdmi
->mpp0
= devm_regulator_get(&pdev
->dev
, "8901_mpp0");
123 if (IS_ERR(hdmi
->mpp0
))
126 hdmi
->clk
= devm_clk_get(&pdev
->dev
, "core_clk");
127 if (IS_ERR(hdmi
->clk
)) {
128 ret
= PTR_ERR(hdmi
->clk
);
129 dev_err(dev
->dev
, "failed to get 'clk': %d\n", ret
);
133 hdmi
->m_pclk
= devm_clk_get(&pdev
->dev
, "master_iface_clk");
134 if (IS_ERR(hdmi
->m_pclk
)) {
135 ret
= PTR_ERR(hdmi
->m_pclk
);
136 dev_err(dev
->dev
, "failed to get 'm_pclk': %d\n", ret
);
140 hdmi
->s_pclk
= devm_clk_get(&pdev
->dev
, "slave_iface_clk");
141 if (IS_ERR(hdmi
->s_pclk
)) {
142 ret
= PTR_ERR(hdmi
->s_pclk
);
143 dev_err(dev
->dev
, "failed to get 's_pclk': %d\n", ret
);
147 hdmi
->i2c
= hdmi_i2c_init(hdmi
);
148 if (IS_ERR(hdmi
->i2c
)) {
149 ret
= PTR_ERR(hdmi
->i2c
);
150 dev_err(dev
->dev
, "failed to get i2c: %d\n", ret
);
155 hdmi
->irq
= platform_get_irq(pdev
, 0);
158 dev_err(dev
->dev
, "failed to get irq: %d\n", ret
);
162 ret
= devm_request_threaded_irq(&pdev
->dev
, hdmi
->irq
,
163 NULL
, hdmi_irq
, IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
166 dev_err(dev
->dev
, "failed to request IRQ%u: %d\n",
184 static int hdmi_dev_probe(struct platform_device
*pdev
)
186 static struct hdmi_platform_config config
= {};
190 if (cpu_is_apq8064()) {
191 config
.phy_init
= hdmi_phy_8960_init
;
192 config
.ddc_clk_gpio
= 70;
193 config
.ddc_data_gpio
= 71;
194 config
.hpd_gpio
= 72;
195 config
.pmic_gpio
= 13 + NR_GPIO_IRQS
;
196 } else if (cpu_is_msm8960()) {
197 config
.phy_init
= hdmi_phy_8960_init
;
198 config
.ddc_clk_gpio
= 100;
199 config
.ddc_data_gpio
= 101;
200 config
.hpd_gpio
= 102;
201 config
.pmic_gpio
= -1;
202 } else if (cpu_is_msm8x60()) {
203 config
.phy_init
= hdmi_phy_8x60_init
;
204 config
.ddc_clk_gpio
= 170;
205 config
.ddc_data_gpio
= 171;
206 config
.hpd_gpio
= 172;
207 config
.pmic_gpio
= -1;
210 pdev
->dev
.platform_data
= &config
;
215 static int hdmi_dev_remove(struct platform_device
*pdev
)
221 static struct platform_driver hdmi_driver
= {
222 .probe
= hdmi_dev_probe
,
223 .remove
= hdmi_dev_remove
,
224 .driver
.name
= "hdmi_msm",
227 void __init
hdmi_register(void)
229 platform_driver_register(&hdmi_driver
);
232 void __exit
hdmi_unregister(void)
234 platform_driver_unregister(&hdmi_driver
);