summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: bf0bd1f)
raw | patch | inline | side by side (parent: bf0bd1f)
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | |
Tue, 26 May 2015 09:59:20 +0000 (12:59 +0300) | ||
committer | Jyri Sarha <jsarha@ti.com> | |
Wed, 27 May 2015 11:43:03 +0000 (14:43 +0300) |
On DRA7 the i2c2 bus is shared between i2c and DDC modes. At the moment
the TPD12S015 driver can switch the muxing at any time, which could lead
to an i2c device getting transfer errors if it is using i2c2 bus.
This patch solves the issue by making TPD12S015 driver use
i2c_lock_adapter() when the pins are in DDC mode.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tested-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
the TPD12S015 driver can switch the muxing at any time, which could lead
to an i2c device getting transfer errors if it is using i2c2 bus.
This patch solves the issue by making TPD12S015 driver use
i2c_lock_adapter() when the pins are in DDC mode.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tested-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
arch/arm/boot/dts/dra7-evm.dts | patch | blob | history | |
drivers/video/fbdev/omap2/displays-new/dra7-evm-encoder-tpd12s015.c | patch | blob | history |
index 53d0403e42cbcb6b372c61205ec830211b769d30..4af20a481bb739acbd0f82164d491a7746e366bd 100644 (file)
pinctrl-0 = <&hdmi_i2c_sel_pin &hdmi_i2c_pins_i2c>;
pinctrl-1 = <&hdmi_i2c_sel_pin &hdmi_i2c_pins_ddc>;
+ ddc-i2c-bus = <&i2c2>;
+
gpios = <&pcf_hdmi 4 0>, /* P4, CT CP HPD */
<&pcf_hdmi 5 0>, /* P5, LS OE */
<&gpio7 12 0>; /* gpio7_12/sp1_cs2, HPD */
diff --git a/drivers/video/fbdev/omap2/displays-new/dra7-evm-encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/dra7-evm-encoder-tpd12s015.c
index d9375c0b5f9c01627a8f8bbb570f1a8a2541ddc5..78b6103b12e9af0d09cd8e7774bfe39a945580e8 100644 (file)
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gpio.h>
+#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
struct pinctrl *pins;
struct pinctrl_state *pin_state_i2c;
struct pinctrl_state *pin_state_ddc;
+
+ struct i2c_adapter *ddc_i2c_adapter;
};
static void __iomem *mcasp2_base;
if (gpio_is_valid(ddata->ls_oe_gpio))
gpio_set_value_cansleep(ddata->ls_oe_gpio, 1);
+ i2c_lock_adapter(ddata->ddc_i2c_adapter);
+
config_demux(dssdev->dev, SEL_HDMI);
r = in->ops.hdmi->read_edid(in, edid, len);
config_demux(dssdev->dev, SEL_I2C2);
+ i2c_unlock_adapter(ddata->ddc_i2c_adapter);
+
if (gpio_is_valid(ddata->ls_oe_gpio))
gpio_set_value_cansleep(ddata->ls_oe_gpio, 0);
static int tpd_init_pins(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct device_node *node;
ddata->pins = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(ddata->pins))
if (IS_ERR(ddata->pin_state_ddc))
return PTR_ERR(ddata->pin_state_ddc);
+ node = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
+ if (!node)
+ return -ENODEV;
+
+ ddata->ddc_i2c_adapter = of_find_i2c_adapter_by_node(node);
+ if (!ddata->ddc_i2c_adapter)
+ return -ENODEV;
+
return 0;
}
+static void tpd_uninit_pins(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+
+ i2c_put_adapter(ddata->ddc_i2c_adapter);
+}
+
static int tpd_probe(struct platform_device *pdev)
{
struct omap_dss_device *in, *dssdev;
err_reg:
err_debounce:
err_gpio:
+ tpd_uninit_pins(pdev);
err_pins:
omap_dss_put_device(ddata->in);
return r;
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
+ tpd_uninit_pins(pdev);
+
omapdss_unregister_output(&ddata->dssdev);
WARN_ON(omapdss_device_is_enabled(dssdev));