summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/bridge/ite-it66121.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2023-01-04 16:59:24 +0300
committerDaniel Vetter <daniel.vetter@ffwll.ch>2023-01-04 16:59:25 +0300
commit03a0a1040895711e12c15ab28d4d1812928e171d (patch)
treeee39720358f6025b5cc171141ba045394a5d41b8 /drivers/gpu/drm/bridge/ite-it66121.c
parentf422fa7cd85832d7d1505d7fae7ae519185354cc (diff)
parent2591939e881cf728b6ac45971eeec2f58051c101 (diff)
downloadlinux-03a0a1040895711e12c15ab28d4d1812928e171d.tar.xz
Merge tag 'drm-misc-next-2023-01-03' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.3: UAPI Changes: * connector: Support analog-TV mode property * media: Add MEDIA_BUS_FMT_RGB565_1X24_CPADHI, MEDIA_BUS_FMT_RGB666_1X18 and MEDIA_BUS_FMT_RGB666_1X24_CPADHI Cross-subsystem Changes: * dma-buf: Documentation fixes * i2c: Introduce i2c_client_get_device_id() helper Core Changes: * Improve support for analog TV output * bridge: Remove unused drm_bridge_chain functions * debugfs: Add per-device helpers and convert various DRM drivers * dp-mst: Various fixes * fbdev emulation: Always pick 32 bpp as default * KUnit: Add tests for managed helpers; Various cleanups * panel-orientation: Add quirks for Lenovo Yoga Tab 3 X90F and DynaBook K50 * TTM: Open-code ttm_bo_wait() and remove the helper Driver Changes: * Fix preferred depth and bpp values throughout DRM drivers * Remove #CONFIG_PM guards throughout DRM drivers * ast: Various fixes * bridge: Implement i2c's probe_new in various drivers; Fixes; ite-it6505: Locking fixes, Cache EDID data; ite-it66121: Support IT6610 chip, Cleanups; lontium-tl9611: Fix HDMI on DragonBoard 845c; parade-ps8640: Use atomic bridge functions * gud: Convert to DRM shadow-plane helpers; Perform flushing synchronously during atomic update * ili9486: Support 16-bit pixel data * imx: Split off IPUv3 driver; Various fixes * mipi-dbi: Convert to DRM shadow-plane helpers plus rsp driver changes;i Support separate I/O-voltage supply * mxsfb: Depend on ARCH_MXS or ARCH_MXC * omapdrm: Various fixes * panel: Use ktime_get_boottime() to measure power-down delay in various drivers; Fix auto-suspend delay in various drivers; orisetech-ota5601a: Add support * sprd: Cleanups * sun4i: Convert to new TV-mode property * tidss: Various fixes * v3d: Various fixes * vc4: Convert to new TV-mode property; Support Kunit tests; Cleanups; dpi: Support RGB565 and RGB666 formats; dsi: Convert DSI driver to bridge * virtio: Improve tracing * vkms: Support small cursors in IGT tests; Various fixes Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/Y7QIwlfElAYWxRcR@linux-uq9g
Diffstat (limited to 'drivers/gpu/drm/bridge/ite-it66121.c')
-rw-r--r--drivers/gpu/drm/bridge/ite-it66121.c320
1 files changed, 156 insertions, 164 deletions
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c
index 4f6f1deba28c..b34860871627 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -35,10 +35,6 @@
#define IT66121_DEVICE_ID0_REG 0x02
#define IT66121_DEVICE_ID1_REG 0x03
-#define IT66121_VENDOR_ID0 0x54
-#define IT66121_VENDOR_ID1 0x49
-#define IT66121_DEVICE_ID0 0x12
-#define IT66121_DEVICE_ID1 0x06
#define IT66121_REVISION_MASK GENMASK(7, 4)
#define IT66121_DEVICE_ID1_MASK GENMASK(3, 0)
@@ -72,6 +68,7 @@
#define IT66121_AFE_XP_ENO BIT(4)
#define IT66121_AFE_XP_RESETB BIT(3)
#define IT66121_AFE_XP_PWDI BIT(2)
+#define IT6610_AFE_XP_BYPASS BIT(0)
#define IT66121_AFE_IP_REG 0x64
#define IT66121_AFE_IP_GAINBIT BIT(7)
@@ -286,13 +283,18 @@
#define IT66121_AUD_SWL_16BIT 0x2
#define IT66121_AUD_SWL_NOT_INDICATED 0x0
-#define IT66121_VENDOR_ID0 0x54
-#define IT66121_VENDOR_ID1 0x49
-#define IT66121_DEVICE_ID0 0x12
-#define IT66121_DEVICE_ID1 0x06
-#define IT66121_DEVICE_MASK 0x0F
#define IT66121_AFE_CLK_HIGH 80000 /* Khz */
+enum chip_id {
+ ID_IT6610,
+ ID_IT66121,
+};
+
+struct it66121_chip_info {
+ enum chip_id id;
+ u16 vid, pid;
+};
+
struct it66121_ctx {
struct regmap *regmap;
struct drm_bridge bridge;
@@ -301,7 +303,6 @@ struct it66121_ctx {
struct device *dev;
struct gpio_desc *gpio_reset;
struct i2c_client *client;
- struct regulator_bulk_data supplies[3];
u32 bus_width;
struct mutex lock; /* Protects fields below and device registers */
struct hdmi_avi_infoframe hdmi_avi_infoframe;
@@ -312,6 +313,7 @@ struct it66121_ctx {
u8 swl;
bool auto_cts;
} audio;
+ const struct it66121_chip_info *info;
};
static const struct regmap_range_cfg it66121_regmap_banks[] = {
@@ -342,16 +344,6 @@ static void it66121_hw_reset(struct it66121_ctx *ctx)
gpiod_set_value(ctx->gpio_reset, 0);
}
-static inline int ite66121_power_on(struct it66121_ctx *ctx)
-{
- return regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
-}
-
-static inline int ite66121_power_off(struct it66121_ctx *ctx)
-{
- return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
-}
-
static inline int it66121_preamble_ddc(struct it66121_ctx *ctx)
{
return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, IT66121_MASTER_SEL_HOST);
@@ -406,16 +398,22 @@ static int it66121_configure_afe(struct it66121_ctx *ctx,
ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG,
IT66121_AFE_IP_GAINBIT |
- IT66121_AFE_IP_ER0 |
- IT66121_AFE_IP_EC1,
+ IT66121_AFE_IP_ER0,
IT66121_AFE_IP_GAINBIT);
if (ret)
return ret;
- ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG,
- IT66121_AFE_XP_EC1_LOWCLK, 0x80);
- if (ret)
- return ret;
+ if (ctx->info->id == ID_IT66121) {
+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG,
+ IT66121_AFE_IP_EC1, 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG,
+ IT66121_AFE_XP_EC1_LOWCLK, 0x80);
+ if (ret)
+ return ret;
+ }
} else {
ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG,
IT66121_AFE_XP_GAINBIT |
@@ -426,17 +424,24 @@ static int it66121_configure_afe(struct it66121_ctx *ctx,
ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG,
IT66121_AFE_IP_GAINBIT |
- IT66121_AFE_IP_ER0 |
- IT66121_AFE_IP_EC1, IT66121_AFE_IP_ER0 |
- IT66121_AFE_IP_EC1);
+ IT66121_AFE_IP_ER0,
+ IT66121_AFE_IP_ER0);
if (ret)
return ret;
- ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG,
- IT66121_AFE_XP_EC1_LOWCLK,
- IT66121_AFE_XP_EC1_LOWCLK);
- if (ret)
- return ret;
+ if (ctx->info->id == ID_IT66121) {
+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG,
+ IT66121_AFE_IP_EC1,
+ IT66121_AFE_IP_EC1);
+ if (ret)
+ return ret;
+
+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG,
+ IT66121_AFE_XP_EC1_LOWCLK,
+ IT66121_AFE_XP_EC1_LOWCLK);
+ if (ret)
+ return ret;
+ }
}
/* Clear reset flags */
@@ -445,38 +450,36 @@ static int it66121_configure_afe(struct it66121_ctx *ctx,
if (ret)
return ret;
+ if (ctx->info->id == ID_IT6610) {
+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG,
+ IT6610_AFE_XP_BYPASS,
+ IT6610_AFE_XP_BYPASS);
+ if (ret)
+ return ret;
+ }
+
return it66121_fire_afe(ctx);
}
static inline int it66121_wait_ddc_ready(struct it66121_ctx *ctx)
{
int ret, val;
- u32 busy = IT66121_DDC_STATUS_NOACK | IT66121_DDC_STATUS_WAIT_BUS |
- IT66121_DDC_STATUS_ARBI_LOSE;
+ u32 error = IT66121_DDC_STATUS_NOACK | IT66121_DDC_STATUS_WAIT_BUS |
+ IT66121_DDC_STATUS_ARBI_LOSE;
+ u32 done = IT66121_DDC_STATUS_TX_DONE;
- ret = regmap_read_poll_timeout(ctx->regmap, IT66121_DDC_STATUS_REG, val, true,
- IT66121_EDID_SLEEP_US, IT66121_EDID_TIMEOUT_US);
+ ret = regmap_read_poll_timeout(ctx->regmap, IT66121_DDC_STATUS_REG, val,
+ val & (error | done), IT66121_EDID_SLEEP_US,
+ IT66121_EDID_TIMEOUT_US);
if (ret)
return ret;
- if (val & busy)
+ if (val & error)
return -EAGAIN;
return 0;
}
-static int it66121_clear_ddc_fifo(struct it66121_ctx *ctx)
-{
- int ret;
-
- ret = it66121_preamble_ddc(ctx);
- if (ret)
- return ret;
-
- return regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG,
- IT66121_DDC_COMMAND_FIFO_CLR);
-}
-
static int it66121_abort_ddc_ops(struct it66121_ctx *ctx)
{
int ret;
@@ -516,7 +519,6 @@ static int it66121_get_edid_block(void *context, u8 *buf,
unsigned int block, size_t len)
{
struct it66121_ctx *ctx = context;
- unsigned int val;
int remain = len;
int offset = 0;
int ret, cnt;
@@ -524,26 +526,9 @@ static int it66121_get_edid_block(void *context, u8 *buf,
offset = (block % 2) * len;
block = block / 2;
- ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val);
- if (ret)
- return ret;
-
- if (val & IT66121_INT_STATUS1_DDC_BUSHANG) {
- ret = it66121_abort_ddc_ops(ctx);
- if (ret)
- return ret;
- }
-
- ret = it66121_clear_ddc_fifo(ctx);
- if (ret)
- return ret;
-
while (remain > 0) {
cnt = (remain > IT66121_EDID_FIFO_SIZE) ?
IT66121_EDID_FIFO_SIZE : remain;
- ret = it66121_preamble_ddc(ctx);
- if (ret)
- return ret;
ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG,
IT66121_DDC_COMMAND_FIFO_CLR);
@@ -554,25 +539,6 @@ static int it66121_get_edid_block(void *context, u8 *buf,
if (ret)
return ret;
- ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val);
- if (ret)
- return ret;
-
- if (val & IT66121_INT_STATUS1_DDC_BUSHANG) {
- ret = it66121_abort_ddc_ops(ctx);
- if (ret)
- return ret;
- }
-
- ret = it66121_preamble_ddc(ctx);
- if (ret)
- return ret;
-
- ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG,
- IT66121_DDC_HEADER_EDID);
- if (ret)
- return ret;
-
ret = regmap_write(ctx->regmap, IT66121_DDC_OFFSET_REG, offset);
if (ret)
return ret;
@@ -593,20 +559,18 @@ static int it66121_get_edid_block(void *context, u8 *buf,
offset += cnt;
remain -= cnt;
- /* Per programming manual, sleep here before emptying the FIFO */
- msleep(20);
-
ret = it66121_wait_ddc_ready(ctx);
+ if (ret) {
+ it66121_abort_ddc_ops(ctx);
+ return ret;
+ }
+
+ ret = regmap_noinc_read(ctx->regmap, IT66121_DDC_RD_FIFO_REG,
+ buf, cnt);
if (ret)
return ret;
- do {
- ret = regmap_read(ctx->regmap, IT66121_DDC_RD_FIFO_REG, &val);
- if (ret)
- return ret;
- *(buf++) = val;
- cnt--;
- } while (cnt > 0);
+ buf += cnt;
}
return 0;
@@ -635,10 +599,12 @@ static int it66121_bridge_attach(struct drm_bridge *bridge,
if (ret)
return ret;
- ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
- IT66121_CLK_BANK_PWROFF_RCLK, 0);
- if (ret)
- return ret;
+ if (ctx->info->id == ID_IT66121) {
+ ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
+ IT66121_CLK_BANK_PWROFF_RCLK, 0);
+ if (ret)
+ return ret;
+ }
ret = regmap_write_bits(ctx->regmap, IT66121_INT_REG,
IT66121_INT_TX_CLK_OFF, 0);
@@ -684,11 +650,7 @@ static int it66121_bridge_attach(struct drm_bridge *bridge,
/* Per programming manual, sleep here for bridge to settle */
msleep(50);
- /* Start interrupts */
- return regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG,
- IT66121_INT_MASK1_DDC_NOACK |
- IT66121_INT_MASK1_DDC_FIFOERR |
- IT66121_INT_MASK1_DDC_BUSHANG, 0);
+ return 0;
}
static int it66121_set_mute(struct it66121_ctx *ctx, bool mute)
@@ -780,29 +742,32 @@ static void it66121_bridge_disable(struct drm_bridge *bridge,
ctx->connector = NULL;
}
+static int it66121_bridge_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
+
+ if (ctx->info->id == ID_IT6610) {
+ /* The IT6610 only supports these settings */
+ bridge_state->input_bus_cfg.flags |= DRM_BUS_FLAG_DE_HIGH |
+ DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
+ bridge_state->input_bus_cfg.flags &=
+ ~DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
+ }
+
+ return 0;
+}
+
static
void it66121_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{
- int ret, i;
u8 buf[HDMI_INFOFRAME_SIZE(AVI)];
struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
- const u16 aviinfo_reg[HDMI_AVI_INFOFRAME_SIZE] = {
- IT66121_AVIINFO_DB1_REG,
- IT66121_AVIINFO_DB2_REG,
- IT66121_AVIINFO_DB3_REG,
- IT66121_AVIINFO_DB4_REG,
- IT66121_AVIINFO_DB5_REG,
- IT66121_AVIINFO_DB6_REG,
- IT66121_AVIINFO_DB7_REG,
- IT66121_AVIINFO_DB8_REG,
- IT66121_AVIINFO_DB9_REG,
- IT66121_AVIINFO_DB10_REG,
- IT66121_AVIINFO_DB11_REG,
- IT66121_AVIINFO_DB12_REG,
- IT66121_AVIINFO_DB13_REG
- };
+ int ret;
mutex_lock(&ctx->lock);
@@ -822,10 +787,12 @@ void it66121_bridge_mode_set(struct drm_bridge *bridge,
}
/* Write new AVI infoframe packet */
- for (i = 0; i < HDMI_AVI_INFOFRAME_SIZE; i++) {
- if (regmap_write(ctx->regmap, aviinfo_reg[i], buf[i + HDMI_INFOFRAME_HEADER_SIZE]))
- goto unlock;
- }
+ ret = regmap_bulk_write(ctx->regmap, IT66121_AVIINFO_DB1_REG,
+ &buf[HDMI_INFOFRAME_HEADER_SIZE],
+ HDMI_AVI_INFOFRAME_SIZE);
+ if (ret)
+ goto unlock;
+
if (regmap_write(ctx->regmap, IT66121_AVIINFO_CSUM_REG, buf[3]))
goto unlock;
@@ -838,9 +805,12 @@ void it66121_bridge_mode_set(struct drm_bridge *bridge,
if (regmap_write(ctx->regmap, IT66121_HDMI_MODE_REG, IT66121_HDMI_MODE_HDMI))
goto unlock;
- if (regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
- IT66121_CLK_BANK_PWROFF_TXCLK, IT66121_CLK_BANK_PWROFF_TXCLK))
+ if (ctx->info->id == ID_IT66121 &&
+ regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
+ IT66121_CLK_BANK_PWROFF_TXCLK,
+ IT66121_CLK_BANK_PWROFF_TXCLK)) {
goto unlock;
+ }
if (it66121_configure_input(ctx))
goto unlock;
@@ -848,7 +818,11 @@ void it66121_bridge_mode_set(struct drm_bridge *bridge,
if (it66121_configure_afe(ctx, adjusted_mode))
goto unlock;
- regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, IT66121_CLK_BANK_PWROFF_TXCLK, 0);
+ if (ctx->info->id == ID_IT66121 &&
+ regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
+ IT66121_CLK_BANK_PWROFF_TXCLK, 0)) {
+ goto unlock;
+ }
unlock:
mutex_unlock(&ctx->lock);
@@ -906,9 +880,25 @@ static struct edid *it66121_bridge_get_edid(struct drm_bridge *bridge,
{
struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, bridge);
struct edid *edid;
+ int ret;
mutex_lock(&ctx->lock);
+ ret = it66121_preamble_ddc(ctx);
+ if (ret) {
+ edid = ERR_PTR(ret);
+ goto out_unlock;
+ }
+
+ ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG,
+ IT66121_DDC_HEADER_EDID);
+ if (ret) {
+ edid = ERR_PTR(ret);
+ goto out_unlock;
+ }
+
edid = drm_do_get_edid(connector, it66121_get_edid_block, ctx);
+
+out_unlock:
mutex_unlock(&ctx->lock);
return edid;
@@ -923,6 +913,7 @@ static const struct drm_bridge_funcs it66121_bridge_funcs = {
.atomic_get_input_bus_fmts = it66121_bridge_atomic_get_input_bus_fmts,
.atomic_enable = it66121_bridge_enable,
.atomic_disable = it66121_bridge_disable,
+ .atomic_check = it66121_bridge_check,
.mode_set = it66121_bridge_mode_set,
.mode_valid = it66121_bridge_mode_valid,
.detect = it66121_bridge_detect,
@@ -952,21 +943,14 @@ static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id)
ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val);
if (ret) {
dev_err(dev, "Cannot read STATUS1_REG %d\n", ret);
- } else {
- if (val & IT66121_INT_STATUS1_DDC_FIFOERR)
- it66121_clear_ddc_fifo(ctx);
- if (val & (IT66121_INT_STATUS1_DDC_BUSHANG |
- IT66121_INT_STATUS1_DDC_NOACK))
- it66121_abort_ddc_ops(ctx);
- if (val & IT66121_INT_STATUS1_HPD_STATUS) {
- regmap_write_bits(ctx->regmap, IT66121_INT_CLR1_REG,
- IT66121_INT_CLR1_HPD, IT66121_INT_CLR1_HPD);
+ } else if (val & IT66121_INT_STATUS1_HPD_STATUS) {
+ regmap_write_bits(ctx->regmap, IT66121_INT_CLR1_REG,
+ IT66121_INT_CLR1_HPD, IT66121_INT_CLR1_HPD);
- status = it66121_is_hpd_detect(ctx) ? connector_status_connected
- : connector_status_disconnected;
+ status = it66121_is_hpd_detect(ctx) ? connector_status_connected
+ : connector_status_disconnected;
- event = true;
- }
+ event = true;
}
regmap_write_bits(ctx->regmap, IT66121_SYS_STATUS_REG,
@@ -1512,9 +1496,13 @@ static int it66121_audio_codec_init(struct it66121_ctx *ctx, struct device *dev)
return PTR_ERR_OR_ZERO(ctx->audio.pdev);
}
-static int it66121_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static const char * const it66121_supplies[] = {
+ "vcn33", "vcn18", "vrf12"
+};
+
+static int it66121_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
struct device_node *ep;
int ret;
@@ -1536,6 +1524,7 @@ static int it66121_probe(struct i2c_client *client,
ctx->dev = dev;
ctx->client = client;
+ ctx->info = (const struct it66121_chip_info *) id->driver_data;
of_property_read_u32(ep, "bus-width", &ctx->bus_width);
of_node_put(ep);
@@ -1565,26 +1554,18 @@ static int it66121_probe(struct i2c_client *client,
i2c_set_clientdata(client, ctx);
mutex_init(&ctx->lock);
- ctx->supplies[0].supply = "vcn33";
- ctx->supplies[1].supply = "vcn18";
- ctx->supplies[2].supply = "vrf12";
- ret = devm_regulator_bulk_get(ctx->dev, 3, ctx->supplies);
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(it66121_supplies),
+ it66121_supplies);
if (ret) {
- dev_err(ctx->dev, "regulator_bulk failed\n");
+ dev_err(dev, "Failed to enable power supplies\n");
return ret;
}
- ret = ite66121_power_on(ctx);
- if (ret)
- return ret;
-
it66121_hw_reset(ctx);
ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config);
- if (IS_ERR(ctx->regmap)) {
- ite66121_power_off(ctx);
+ if (IS_ERR(ctx->regmap))
return PTR_ERR(ctx->regmap);
- }
regmap_read(ctx->regmap, IT66121_VENDOR_ID0_REG, &vendor_ids[0]);
regmap_read(ctx->regmap, IT66121_VENDOR_ID1_REG, &vendor_ids[1]);
@@ -1595,9 +1576,8 @@ static int it66121_probe(struct i2c_client *client,
revision_id = FIELD_GET(IT66121_REVISION_MASK, device_ids[1]);
device_ids[1] &= IT66121_DEVICE_ID1_MASK;
- if (vendor_ids[0] != IT66121_VENDOR_ID0 || vendor_ids[1] != IT66121_VENDOR_ID1 ||
- device_ids[0] != IT66121_DEVICE_ID0 || device_ids[1] != IT66121_DEVICE_ID1) {
- ite66121_power_off(ctx);
+ if ((vendor_ids[1] << 8 | vendor_ids[0]) != ctx->info->vid ||
+ (device_ids[1] << 8 | device_ids[0]) != ctx->info->pid) {
return -ENODEV;
}
@@ -1610,7 +1590,6 @@ static int it66121_probe(struct i2c_client *client,
IRQF_ONESHOT, dev_name(dev), ctx);
if (ret < 0) {
dev_err(dev, "Failed to request irq %d:%d\n", client->irq, ret);
- ite66121_power_off(ctx);
return ret;
}
@@ -1627,19 +1606,32 @@ static void it66121_remove(struct i2c_client *client)
{
struct it66121_ctx *ctx = i2c_get_clientdata(client);
- ite66121_power_off(ctx);
drm_bridge_remove(&ctx->bridge);
mutex_destroy(&ctx->lock);
}
static const struct of_device_id it66121_dt_match[] = {
{ .compatible = "ite,it66121" },
+ { .compatible = "ite,it6610" },
{ }
};
MODULE_DEVICE_TABLE(of, it66121_dt_match);
+static const struct it66121_chip_info it66121_chip_info = {
+ .id = ID_IT66121,
+ .vid = 0x4954,
+ .pid = 0x0612,
+};
+
+static const struct it66121_chip_info it6610_chip_info = {
+ .id = ID_IT6610,
+ .vid = 0xca00,
+ .pid = 0x0611,
+};
+
static const struct i2c_device_id it66121_id[] = {
- { "it66121", 0 },
+ { "it66121", (kernel_ulong_t) &it66121_chip_info },
+ { "it6610", (kernel_ulong_t) &it6610_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, it66121_id);
@@ -1649,7 +1641,7 @@ static struct i2c_driver it66121_driver = {
.name = "it66121",
.of_match_table = it66121_dt_match,
},
- .probe = it66121_probe,
+ .probe_new = it66121_probe,
.remove = it66121_remove,
.id_table = it66121_id,
};