From patchwork Mon Jan 22 12:49:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 864250 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=sendgrid.me header.i=@sendgrid.me header.b="B3V5bR4c"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zQBJH1Chhz9s7s for ; Mon, 22 Jan 2018 23:56:15 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751106AbeAVM4O (ORCPT ); Mon, 22 Jan 2018 07:56:14 -0500 Received: from o1.7nn.fshared.sendgrid.net ([167.89.55.65]:59762 "EHLO o1.7nn.fshared.sendgrid.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751024AbeAVM4N (ORCPT ); Mon, 22 Jan 2018 07:56:13 -0500 X-Greylist: delayed 339 seconds by postgrey-1.27 at vger.kernel.org; Mon, 22 Jan 2018 07:56:13 EST DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=sendgrid.me; h=from:to:cc:subject:in-reply-to:references:mime-version:content-type:content-transfer-encoding; s=smtpapi; bh=TFJrw6sps6pamwrhOnlBVykGNUs=; b=B3V5bR4cAWm9jH/zC4 piRYjcb14WYJ9fO6y1RfoG011vOZGvfrB32ABNbYOFIWQEB4du+s3/QNV9/YmDzI 2BfHQ9SCfjlySWuICSXfA2yrMrGr6MWnmbf+AuTkKOMzzUp9oKYtFuj7RAxST1cd RwSF1nArvUDxD6gV4rn3NMb4k= Received: by filter0017p3iad2.sendgrid.net with SMTP id filter0017p3iad2-18204-5A65DDF1-66 2018-01-22 12:49:54.71119606 +0000 UTC Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by ismtpd0003p1lon1.sendgrid.net (SG) with ESMTP id ZIVYYB19SmiCnCd5XReyrw Mon, 22 Jan 2018 12:49:53.841 +0000 (UTC) From: Kieran Bingham To: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: Jean-Michel Hautbois , Kieran Bingham , Mauro Carvalho Chehab , Rob Herring , Mark Rutland , Hans Verkuil , devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS) Subject: [PATCH 1/2] media: adv7604: Add support for i2c_new_secondary_device Date: Mon, 22 Jan 2018 12:49:56 +0000 (UTC) Message-Id: <1516625389-6362-2-git-send-email-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516625389-6362-1-git-send-email-kieran.bingham@ideasonboard.com> References: <1516625389-6362-1-git-send-email-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 content-transfer-encoding: quoted-printable X-SG-EID: 1rpbF89YqQdTiByq/OjCsd9RZIOJb/oK7G1OMOpWCLVs5mKztPkBbjT4UduLgj65AGKLab41NTurJ0 05JJmmXmzZCPHGFp3BjdsRungytZ0MU3stq943wiVm3wj9sAQlqq/dHa4Iy9WggTNB4moY3NZhoLsp Qr0v7hTvXsYdtDxH8DIzuDEvJ5+qM52dLqSXgiukfNdU2SwTCS/vWzr2Bt0JF2NxMNqM2K6E9LHvfL ArDbIP7S9oUFZrMt70rGCg Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Jean-Michel Hautbois The ADV7604 has thirteen 256-byte maps that can be accessed via the main I²C ports. Each map has it own I²C address and acts as a standard slave device on the I²C bus. Allow a device tree node to override the default addresses so that address conflicts with other devices on the same bus may be resolved at the board description level. Signed-off-by: Jean-Michel Hautbois [Kieran: Re-adapted for mainline] Signed-off-by: Kieran Bingham Reviewed-by: Rob Herring --- Based upon the original posting : https://lkml.org/lkml/2014/10/22/469 --- .../devicetree/bindings/media/i2c/adv7604.txt | 18 ++++++- drivers/media/i2c/adv7604.c | 60 ++++++++++++++-------- 2 files changed, 55 insertions(+), 23 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index 9cbd92eb5d05..b64e313dcc66 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt @@ -13,7 +13,11 @@ Required Properties: - "adi,adv7611" for the ADV7611 - "adi,adv7612" for the ADV7612 - - reg: I2C slave address + - reg: I2C slave addresses + The ADV76xx has up to thirteen 256-byte maps that can be accessed via the + main I²C ports. Each map has it own I²C address and acts as a standard + slave device on the I²C bus. The main address is mandatory, others are + optional and revert to defaults if not specified. - hpd-gpios: References to the GPIOs that control the HDMI hot-plug detection pins, one per HDMI input. The active flag indicates the GPIO @@ -35,6 +39,11 @@ Optional Properties: - reset-gpios: Reference to the GPIO connected to the device's reset pin. - default-input: Select which input is selected after reset. + - reg-names : Names of maps with programmable addresses. + It can contain any map needing a non-default address. + Possible maps names are : + "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe", + "rep", "edid", "hdmi", "test", "cp", "vdp" Optional Endpoint Properties: @@ -52,7 +61,12 @@ Example: hdmi_receiver@4c { compatible = "adi,adv7611"; - reg = <0x4c>; + /* + * The edid page will be accessible @ 0x66 on the i2c bus. All + * other maps will retain their default addresses. + */ + reg = <0x4c 0x66>; + reg-names "main", "edid"; reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 1544920ec52d..c346b9a8fb57 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2734,6 +2734,27 @@ static const struct v4l2_ctrl_config adv76xx_ctrl_free_run_color = { /* ----------------------------------------------------------------------- */ +struct adv76xx_register { + const char *name; + u8 default_addr; +}; + +static const struct adv76xx_register adv76xx_secondary_names[] = { + [ADV76XX_PAGE_IO] = { "main", 0x4c }, + [ADV7604_PAGE_AVLINK] = { "avlink", 0x42 }, + [ADV76XX_PAGE_CEC] = { "cec", 0x40 }, + [ADV76XX_PAGE_INFOFRAME] = { "infoframe", 0x3e }, + [ADV7604_PAGE_ESDP] = { "esdp", 0x38 }, + [ADV7604_PAGE_DPP] = { "dpp", 0x3c }, + [ADV76XX_PAGE_AFE] = { "afe", 0x26 }, + [ADV76XX_PAGE_REP] = { "rep", 0x32 }, + [ADV76XX_PAGE_EDID] = { "edid", 0x36 }, + [ADV76XX_PAGE_HDMI] = { "hdmi", 0x34 }, + [ADV76XX_PAGE_TEST] = { "test", 0x30 }, + [ADV76XX_PAGE_CP] = { "cp", 0x22 }, + [ADV7604_PAGE_VDP] = { "vdp", 0x24 }, +}; + static int adv76xx_core_init(struct v4l2_subdev *sd) { struct adv76xx_state *state = to_state(sd); @@ -2834,13 +2855,26 @@ static void adv76xx_unregister_clients(struct adv76xx_state *state) } static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd, - u8 addr, u8 io_reg) + unsigned int i) { struct i2c_client *client = v4l2_get_subdevdata(sd); + struct adv76xx_state *state = to_state(sd); + struct adv76xx_platform_data *pdata = &state->pdata; + unsigned int io_reg = 0xf2 + i; + struct i2c_client *new_client; + + if (pdata && pdata->i2c_addresses[i]) + new_client = i2c_new_dummy(client->adapter, + pdata->i2c_addresses[i]); + else + new_client = i2c_new_secondary_device(client, + adv76xx_secondary_names[i].name, + adv76xx_secondary_names[i].default_addr); - if (addr) - io_write(sd, io_reg, addr << 1); - return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); + if (new_client) + io_write(sd, io_reg, new_client->addr << 1); + + return new_client; } static const struct adv76xx_reg_seq adv7604_recommended_settings_afe[] = { @@ -3115,20 +3149,6 @@ static int adv76xx_parse_dt(struct adv76xx_state *state) /* Disable the interrupt for now as no DT-based board uses it. */ state->pdata.int1_config = ADV76XX_INT1_CONFIG_DISABLED; - /* Use the default I2C addresses. */ - state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42; - state->pdata.i2c_addresses[ADV76XX_PAGE_CEC] = 0x40; - state->pdata.i2c_addresses[ADV76XX_PAGE_INFOFRAME] = 0x3e; - state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38; - state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c; - state->pdata.i2c_addresses[ADV76XX_PAGE_AFE] = 0x26; - state->pdata.i2c_addresses[ADV76XX_PAGE_REP] = 0x32; - state->pdata.i2c_addresses[ADV76XX_PAGE_EDID] = 0x36; - state->pdata.i2c_addresses[ADV76XX_PAGE_HDMI] = 0x34; - state->pdata.i2c_addresses[ADV76XX_PAGE_TEST] = 0x30; - state->pdata.i2c_addresses[ADV76XX_PAGE_CP] = 0x22; - state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24; - /* Hardcode the remaining platform data fields. */ state->pdata.disable_pwrdnb = 0; state->pdata.disable_cable_det_rst = 0; @@ -3478,9 +3498,7 @@ static int adv76xx_probe(struct i2c_client *client, if (!(BIT(i) & state->info->page_mask)) continue; - state->i2c_clients[i] = - adv76xx_dummy_client(sd, state->pdata.i2c_addresses[i], - 0xf2 + i); + state->i2c_clients[i] = adv76xx_dummy_client(sd, i); if (!state->i2c_clients[i]) { err = -ENOMEM; v4l2_err(sd, "failed to create i2c client %u\n", i); From patchwork Mon Jan 22 12:50:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 864251 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=sendgrid.me header.i=@sendgrid.me header.b="PQx+LPV9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zQBMf3F7mz9s74 for ; Mon, 22 Jan 2018 23:59:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751041AbeAVM7J (ORCPT ); Mon, 22 Jan 2018 07:59:09 -0500 Received: from o1678950229.outbound-mail.sendgrid.net ([167.89.50.229]:50957 "EHLO o1678950229.outbound-mail.sendgrid.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750970AbeAVM7J (ORCPT ); Mon, 22 Jan 2018 07:59:09 -0500 X-Greylist: delayed 547 seconds by postgrey-1.27 at vger.kernel.org; Mon, 22 Jan 2018 07:59:08 EST DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=sendgrid.me; h=from:to:cc:subject:in-reply-to:references:mime-version:content-type:content-transfer-encoding; s=smtpapi; bh=4MjbNRh/dmpkKdePfTFLz2YLAZw=; b=PQx+LPV9sRXbjY/F75 SFu/Q7TJyXnUvMRpCnEm4h0U2htMXgg499gH0s7d6ZIvSklmZsJgOoCafMHq0Q45 cSGZsHDlXHRinEVif5SddzcCIvCTJDPqi7suv72gd5NWRzJPFmM/yTjWxHDTlDUn 5MKK9QSJNC3O8rnbQ3aZ0rxmQ= Received: by filter0021p3iad2.sendgrid.net with SMTP id filter0021p3iad2-13808-5A65DDF6-54 2018-01-22 12:49:59.281163003 +0000 UTC Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by ismtpd0003p1lon1.sendgrid.net (SG) with ESMTP id d40DEnEMSBGSavij_lD6pw Mon, 22 Jan 2018 12:49:58.785 +0000 (UTC) From: Kieran Bingham To: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: Jean-Michel Hautbois , Kieran Bingham , David Airlie , Rob Herring , Mark Rutland , Archit Taneja , Andrzej Hajda , Laurent Pinchart , John Stultz , Mark Brown , Hans Verkuil , Lars-Peter Clausen , Daniel Vetter , Bhumika Goyal , Inki Dae , devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS) Subject: [PATCH 2/2] drm: adv7511: Add support for i2c_new_secondary_device Date: Mon, 22 Jan 2018 12:50:01 +0000 (UTC) Message-Id: <1516625389-6362-3-git-send-email-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516625389-6362-1-git-send-email-kieran.bingham@ideasonboard.com> References: <1516625389-6362-1-git-send-email-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 content-transfer-encoding: quoted-printable X-SG-EID: 1rpbF89YqQdTiByq/OjCsd9RZIOJb/oK7G1OMOpWCLW2kEfV96ULu1LaPhU/DMIH6CY8pRDRXoLVGq +SDcOsKIC7WLYq3UYZKkgMY78OVYTl5Oo+bK8HMf4AEHVEPJPNZWih+CtGawdFSK8o0TjWWydwZeIN HlmiSgjtZ8aPEF53OzdmR4nWJ6AbH5mMaRJz6k2BLz3t//BXW9wrsqOKo4cC/DI3rktJyzzcNI00rO lfK26zEkcZEbFEkQB6dQWb Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The ADV7511 has four 256-byte maps that can be accessed via the main I²C ports. Each map has it own I²C address and acts as a standard slave device on the I²C bus. Allow a device tree node to override the default addresses so that address conflicts with other devices on the same bus may be resolved at the board description level. Signed-off-by: Kieran Bingham Reviewed-by: Rob Herring --- .../bindings/display/bridge/adi,adv7511.txt | 10 +++++- drivers/gpu/drm/bridge/adv7511/adv7511.h | 4 +++ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 36 ++++++++++++++-------- 3 files changed, 37 insertions(+), 13 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt index 0047b1394c70..f6bb9f6d3f48 100644 --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt @@ -70,6 +70,9 @@ Optional properties: rather than generate its own timings for HDMI output. - clocks: from common clock binding: reference to the CEC clock. - clock-names: from common clock binding: must be "cec". +- reg-names : Names of maps with programmable addresses. + It can contain any map needing a non-default address. + Possible maps names are : "main", "edid", "cec", "packet" Required nodes: @@ -88,7 +91,12 @@ Example adv7511w: hdmi@39 { compatible = "adi,adv7511w"; - reg = <39>; + /* + * The EDID page will be accessible on address 0x66 on the i2c + * bus. All other maps continue to use their default addresses. + */ + reg = <0x39 0x66>; + reg-names = "main", "edid"; interrupt-parent = <&gpio3>; interrupts = <29 IRQ_TYPE_EDGE_FALLING>; clocks = <&cec_clock>; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index d034b2cb5eee..7d81ce3808e0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -53,8 +53,10 @@ #define ADV7511_REG_POWER 0x41 #define ADV7511_REG_STATUS 0x42 #define ADV7511_REG_EDID_I2C_ADDR 0x43 +#define ADV7511_REG_EDID_I2C_ADDR_DEFAULT 0x3f #define ADV7511_REG_PACKET_ENABLE1 0x44 #define ADV7511_REG_PACKET_I2C_ADDR 0x45 +#define ADV7511_REG_PACKET_I2C_ADDR_DEFAULT 0x38 #define ADV7511_REG_DSD_ENABLE 0x46 #define ADV7511_REG_VIDEO_INPUT_CFG2 0x48 #define ADV7511_REG_INFOFRAME_UPDATE 0x4a @@ -89,6 +91,7 @@ #define ADV7511_REG_TMDS_CLOCK_INV 0xde #define ADV7511_REG_ARC_CTRL 0xdf #define ADV7511_REG_CEC_I2C_ADDR 0xe1 +#define ADV7511_REG_CEC_I2C_ADDR_DEFAULT 0x3c #define ADV7511_REG_CEC_CTRL 0xe2 #define ADV7511_REG_CHIP_ID_HIGH 0xf5 #define ADV7511_REG_CHIP_ID_LOW 0xf6 @@ -322,6 +325,7 @@ struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; struct i2c_client *i2c_cec; + struct i2c_client *i2c_packet; struct regmap *regmap; struct regmap *regmap_cec; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index efa29db5fc2b..7ec33837752b 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -969,8 +969,8 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) { int ret; - adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter, - adv->i2c_main->addr - 1); + adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec", + ADV7511_REG_CEC_I2C_ADDR_DEFAULT); if (!adv->i2c_cec) return -ENOMEM; i2c_set_clientdata(adv->i2c_cec, adv); @@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) struct adv7511_link_config link_config; struct adv7511 *adv7511; struct device *dev = &i2c->dev; - unsigned int main_i2c_addr = i2c->addr << 1; - unsigned int edid_i2c_addr = main_i2c_addr + 4; unsigned int val; int ret; @@ -1153,24 +1151,35 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) if (ret) goto uninit_regulators; - regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); - regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, - main_i2c_addr - 0xa); - regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, - main_i2c_addr - 2); - adv7511_packet_disable(adv7511, 0xffff); - adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); + adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid", + ADV7511_REG_EDID_I2C_ADDR_DEFAULT); if (!adv7511->i2c_edid) { ret = -ENOMEM; goto uninit_regulators; } + regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, + adv7511->i2c_edid->addr << 1); + ret = adv7511_init_cec_regmap(adv7511); if (ret) goto err_i2c_unregister_edid; + regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, + adv7511->i2c_cec->addr << 1); + + adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet", + ADV7511_REG_PACKET_I2C_ADDR_DEFAULT); + if (!adv7511->i2c_packet) { + ret = -ENOMEM; + goto err_unregister_cec; + } + + regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, + adv7511->i2c_packet->addr << 1); + INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); if (i2c->irq) { @@ -1181,7 +1190,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) IRQF_ONESHOT, dev_name(dev), adv7511); if (ret) - goto err_unregister_cec; + goto err_unregister_packet; } adv7511_power_off(adv7511); @@ -1203,6 +1212,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) adv7511_audio_init(dev, adv7511); return 0; +err_unregister_packet: + i2c_unregister_device(adv7511->i2c_packet); err_unregister_cec: i2c_unregister_device(adv7511->i2c_cec); if (adv7511->cec_clk) @@ -1234,6 +1245,7 @@ static int adv7511_remove(struct i2c_client *i2c) cec_unregister_adapter(adv7511->cec_adap); i2c_unregister_device(adv7511->i2c_edid); + i2c_unregister_device(adv7511->i2c_packet); return 0; }