File Index
Files and directories
Sign in
FILE

hibmc_drm_i2c.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/* Hisilicon Hibmc SoC drm driver
  3 *
  4 * Based on the bochs drm driver.
  5 *
  6 * Copyright (c) 2016 Huawei Limited.
  7 *
  8 * Author:
  9 *      Tian Tao <tiantao6@hisilicon.com>
 10 */
 11
 12#include <linux/delay.h>
 13#include <linux/pci.h>
 14
 15#include <drm/drm_atomic_helper.h>
 16#include <drm/drm_probe_helper.h>
 17
 18#include "hibmc_drm_drv.h"
 19
 20#define GPIO_DATA		0x0802A0
 21#define GPIO_DATA_DIRECTION	0x0802A4
 22
 23#define I2C_SCL_MASK		BIT(0)
 24#define I2C_SDA_MASK		BIT(1)
 25
 26static void hibmc_set_i2c_signal(void *data, u32 mask, int value)
 27{
 28	struct hibmc_vdac *vdac = data;
 29	struct hibmc_drm_private *priv = to_hibmc_drm_private(vdac->connector.dev);
 30	u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
 31
 32	if (value) {
 33		tmp_dir &= ~mask;
 34		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
 35	} else {
 36		u32 tmp_data = readl(priv->mmio + GPIO_DATA);
 37
 38		tmp_data &= ~mask;
 39		writel(tmp_data, priv->mmio + GPIO_DATA);
 40
 41		tmp_dir |= mask;
 42		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
 43	}
 44}
 45
 46static int hibmc_get_i2c_signal(void *data, u32 mask)
 47{
 48	struct hibmc_vdac *vdac = data;
 49	struct hibmc_drm_private *priv = to_hibmc_drm_private(vdac->connector.dev);
 50	u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION);
 51
 52	if ((tmp_dir & mask) != mask) {
 53		tmp_dir &= ~mask;
 54		writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION);
 55	}
 56
 57	return (readl(priv->mmio + GPIO_DATA) & mask) ? 1 : 0;
 58}
 59
 60static void hibmc_ddc_setsda(void *data, int state)
 61{
 62	hibmc_set_i2c_signal(data, I2C_SDA_MASK, state);
 63}
 64
 65static void hibmc_ddc_setscl(void *data, int state)
 66{
 67	hibmc_set_i2c_signal(data, I2C_SCL_MASK, state);
 68}
 69
 70static int hibmc_ddc_getsda(void *data)
 71{
 72	return hibmc_get_i2c_signal(data, I2C_SDA_MASK);
 73}
 74
 75static int hibmc_ddc_getscl(void *data)
 76{
 77	return hibmc_get_i2c_signal(data, I2C_SCL_MASK);
 78}
 79
 80int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac)
 81{
 82	vdac->adapter.owner = THIS_MODULE;
 83	snprintf(vdac->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus");
 84	vdac->adapter.dev.parent = drm_dev->dev;
 85	i2c_set_adapdata(&vdac->adapter, vdac);
 86	vdac->adapter.algo_data = &vdac->bit_data;
 87
 88	vdac->bit_data.udelay = 20;
 89	vdac->bit_data.timeout = usecs_to_jiffies(2000);
 90	vdac->bit_data.data = vdac;
 91	vdac->bit_data.setsda = hibmc_ddc_setsda;
 92	vdac->bit_data.setscl = hibmc_ddc_setscl;
 93	vdac->bit_data.getsda = hibmc_ddc_getsda;
 94	vdac->bit_data.getscl = hibmc_ddc_getscl;
 95
 96	return i2c_bit_add_bus(&vdac->adapter);
 97}
 98
 99void hibmc_ddc_del(struct hibmc_vdac *vdac)
100{
101	i2c_del_adapter(&vdac->adapter);
102}
~/ Read-only file preview.