0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013 #include <linux/pci.h>
0014
0015 #include <drm/drm_atomic_helper.h>
0016 #include <drm/drm_probe_helper.h>
0017
0018 #include "hibmc_drm_drv.h"
0019
0020 #define GPIO_DATA 0x0802A0
0021 #define GPIO_DATA_DIRECTION 0x0802A4
0022
0023 #define I2C_SCL_MASK BIT(0)
0024 #define I2C_SDA_MASK BIT(1)
0025
0026 static void hibmc_set_i2c_signal(void *data, u32 mask, int value)
0027 {
0028 struct hibmc_connector *hibmc_connector = data;
0029 struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev);
0030 u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
0031
0032 if (value) {
0033 tmp_dir &= ~mask;
0034 writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
0035 } else {
0036 u32 tmp_data = readl(priv->mmio + GPIO_DATA);
0037
0038 tmp_data &= ~mask;
0039 writel(tmp_data, priv->mmio + GPIO_DATA);
0040
0041 tmp_dir |= mask;
0042 writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
0043 }
0044 }
0045
0046 static int hibmc_get_i2c_signal(void *data, u32 mask)
0047 {
0048 struct hibmc_connector *hibmc_connector = data;
0049 struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev);
0050 u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
0051
0052 if ((tmp_dir & mask) != mask) {
0053 tmp_dir &= ~mask;
0054 writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
0055 }
0056
0057 return (readl(priv->mmio + GPIO_DATA) & mask) ? 1 : 0;
0058 }
0059
0060 static void hibmc_ddc_setsda(void *data, int state)
0061 {
0062 hibmc_set_i2c_signal(data, I2C_SDA_MASK, state);
0063 }
0064
0065 static void hibmc_ddc_setscl(void *data, int state)
0066 {
0067 hibmc_set_i2c_signal(data, I2C_SCL_MASK, state);
0068 }
0069
0070 static int hibmc_ddc_getsda(void *data)
0071 {
0072 return hibmc_get_i2c_signal(data, I2C_SDA_MASK);
0073 }
0074
0075 static int hibmc_ddc_getscl(void *data)
0076 {
0077 return hibmc_get_i2c_signal(data, I2C_SCL_MASK);
0078 }
0079
0080 int hibmc_ddc_create(struct drm_device *drm_dev,
0081 struct hibmc_connector *connector)
0082 {
0083 connector->adapter.owner = THIS_MODULE;
0084 connector->adapter.class = I2C_CLASS_DDC;
0085 snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus");
0086 connector->adapter.dev.parent = drm_dev->dev;
0087 i2c_set_adapdata(&connector->adapter, connector);
0088 connector->adapter.algo_data = &connector->bit_data;
0089
0090 connector->bit_data.udelay = 20;
0091 connector->bit_data.timeout = usecs_to_jiffies(2000);
0092 connector->bit_data.data = connector;
0093 connector->bit_data.setsda = hibmc_ddc_setsda;
0094 connector->bit_data.setscl = hibmc_ddc_setscl;
0095 connector->bit_data.getsda = hibmc_ddc_getsda;
0096 connector->bit_data.getscl = hibmc_ddc_getscl;
0097
0098 return i2c_bit_add_bus(&connector->adapter);
0099 }