From patchwork Fri Feb 1 08:11:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Kurtz X-Patchwork-Id: 2077711 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 761EA40E3D for ; Fri, 1 Feb 2013 08:14:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755644Ab3BAIN7 (ORCPT ); Fri, 1 Feb 2013 03:13:59 -0500 Received: from mail-pb0-f51.google.com ([209.85.160.51]:60120 "EHLO mail-pb0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756057Ab3BAIM1 (ORCPT ); Fri, 1 Feb 2013 03:12:27 -0500 Received: by mail-pb0-f51.google.com with SMTP id un15so2037652pbc.38 for ; Fri, 01 Feb 2013 00:12:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=M6fOUYA1qW+v/7pX2/PoU98RIj6Fhaoj+tJn64cSWeI=; b=cLfct57/TMgHAMvbTBxcLA8deBcPNaGsRrKktpm78B93dtIOIlkAutqeusb1Gpc/b7 rc1Y1XUSEEvGM+3LQF4M1If3bILmA4YKSOT6F/NVb3GGVG/kXbiTE+hqec7PPu5gXQBp oZk6kC3tXz+B4i+JUjpVxgPjZfO9wP0aFYgbo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=M6fOUYA1qW+v/7pX2/PoU98RIj6Fhaoj+tJn64cSWeI=; b=n7SUe9N0i5PET6N4s3HTyccRJ/MwZUbN5oZSMGnOEDxahD1Q4p+AetQX3xVgmvr6EI w9K/K76Ezn/0LQyzp0ih2mei7FWOoQSxv184IOpMdVr5crLtfb9swzxHLM7nQzZf/kqu ymHCh2LtcWyJ2dfxSj4+FvWPGYd4MfofMTHMNQJ1FhnUaT1umlOIAUlrdYMc/Tsg5x1+ E7i/iOj903O1ZvuaJ1E+rsdwZDxSymPJASNPmElJzMwlyL/NkCcpcJC7gvEstCpQY256 WFBmuVGoWWv9h1vrDbtq2hibUYigbOl8fD/AGFAN9VSuvvxbCkDFFSni2rNt2ESOlk7q gdKw== X-Received: by 10.68.197.71 with SMTP id is7mr29760791pbc.79.1359706345930; Fri, 01 Feb 2013 00:12:25 -0800 (PST) Received: from djkurtz-z620.tpe.corp.google.com (djkurtz-z620.tpe.corp.google.com [172.30.210.61]) by mx.google.com with ESMTPS id bi8sm8398002pab.15.2013.02.01.00.12.22 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 01 Feb 2013 00:12:24 -0800 (PST) From: Daniel Kurtz To: Dmitry Torokhov , Henrik Rydberg , Benson Leung , Yufeng Shen , Nick Dyer Cc: Joonyoung Shim , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, olofj@chromium.org, Daniel Kurtz Subject: [PATCH 07/10] Input: atmel_mxt_ts - refactor bootloader entry/exit Date: Fri, 1 Feb 2013 16:11:49 +0800 Message-Id: <1359706312-24642-8-git-send-email-djkurtz@chromium.org> X-Mailer: git-send-email 1.8.1 In-Reply-To: <1359706312-24642-1-git-send-email-djkurtz@chromium.org> References: <1359706312-24642-1-git-send-email-djkurtz@chromium.org> X-Gm-Message-State: ALoCoQkg5v2woqQymC03n8UWNchdq6uXFLEQ2HGsCNxIS0WoMpm8AeN3wNJv/OOrXtQQ6jBjdFvW Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Benson Leung Refactor bootloading into a three parts: 1) bl enter that only happens when device is not yet in bl. bl enter frees old driver state and switches to BL i2c addr. 2) the actual fw_update 3) bl exit that only happens if fw update is successful. bl exit switches to APP i2c addr and reloads object table and creates a new input device. Signed-off-by: Benson Leung Signed-off-by: Daniel Kurtz Signed-off-by: Yufeng Shen --- drivers/input/touchscreen/atmel_mxt_ts.c | 128 +++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 41 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c74f5a5..be96be3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -253,6 +253,11 @@ struct mxt_data { u8 T9_reportid_max; }; +static void mxt_free_object_table(struct mxt_data *data); +static int mxt_initialize(struct mxt_data *data); +static int mxt_input_dev_create(struct mxt_data *data); +static int mxt_make_highchg(struct mxt_data *data); + static bool mxt_object_readable(unsigned int type) { switch (type) { @@ -402,6 +407,8 @@ recheck: if (val != state) { dev_err(&client->dev, "Unvalid bootloader mode state\n"); + dev_err(&client->dev, "Invalid bootloader mode state %d, %d\n", + val, state); return -EINVAL; } @@ -581,6 +588,81 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) return (id >= data->T9_reportid_min && id <= data->T9_reportid_max); } +static int mxt_enter_bl(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int ret; + + if (mxt_in_bootloader(data)) + return 0; + + disable_irq(data->irq); + + /* Change to the bootloader mode */ + ret = mxt_write_object(data, MXT_GEN_COMMAND_T6, + MXT_COMMAND_RESET, MXT_BOOT_VALUE); + if (ret) { + enable_irq(data->irq); + return ret; + } + + /* Change to slave address of bootloader */ + if (client->addr == MXT_APP_LOW) + client->addr = MXT_BOOT_LOW; + else + client->addr = MXT_BOOT_HIGH; + + /* Free any driver state. It will get reinitialized after fw update. */ + mxt_free_object_table(data); + if (data->input_dev) { + input_unregister_device(data->input_dev); + data->input_dev = NULL; + } + + enable_irq(data->irq); + msleep(MXT_RESET_TIME); + return 0; +} + +static void mxt_exit_bl(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + struct device *dev = &client->dev; + int error; + + if (!mxt_in_bootloader(data)) + return; + + disable_irq(data->irq); + /* Wait for reset */ + msleep(MXT_FWRESET_TIME); + + if (client->addr == MXT_BOOT_LOW) + client->addr = MXT_APP_LOW; + else + client->addr = MXT_APP_HIGH; + + error = mxt_initialize(data); + if (error) { + dev_err(dev, "Failed to initialize on exit bl. error = %d\n", + error); + return; + } + + error = mxt_input_dev_create(data); + if (error) { + dev_err(dev, "Create input dev failed after init. error = %d\n", + error); + return; + } + + error = mxt_make_highchg(data); + if (error) + dev_err(dev, "Failed to clear CHG after init. error = %d\n", + error); + enable_irq(data->irq); +} + static irqreturn_t mxt_interrupt(int irq, void *dev_id) { struct mxt_data *data = dev_id; @@ -984,28 +1066,10 @@ static int mxt_load_fw(struct device *dev, const char *fn) return ret; } - if (mxt_in_bootloader(data)) - goto bootloader_ready; - - /* Change to the bootloader mode */ - ret = mxt_write_object(data, MXT_GEN_COMMAND_T6, - MXT_COMMAND_RESET, MXT_BOOT_VALUE); - if (ret) + ret = mxt_enter_bl(data); + if (ret) { + dev_err(dev, "Failed to reset to bootloader.\n"); goto out; - msleep(MXT_RESET_TIME); - - /* Change to slave address of bootloader */ - if (client->addr == MXT_APP_LOW) - client->addr = MXT_BOOT_LOW; - else - client->addr = MXT_BOOT_HIGH; - -bootloader_ready: - /* Free any driver state. It will get reinitialized after fw update. */ - mxt_free_object_table(data); - if (data->input_dev) { - input_unregister_device(data->input_dev); - data->input_dev = NULL; } ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD); @@ -1045,11 +1109,8 @@ bootloader_ready: dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); } - /* Change to slave address of application */ - if (client->addr == MXT_BOOT_LOW) - client->addr = MXT_APP_LOW; - else - client->addr = MXT_APP_HIGH; + /* Device exits bl mode to app mode only if successful */ + mxt_exit_bl(data); out: release_firmware(fw); @@ -1060,31 +1121,16 @@ static ssize_t mxt_update_fw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct mxt_data *data = dev_get_drvdata(dev); int error; - disable_irq(data->irq); - error = mxt_load_fw(dev, MXT_FW_NAME); if (error) { dev_err(dev, "The firmware update failed(%d)\n", error); count = error; } else { dev_dbg(dev, "The firmware update succeeded\n"); - - /* Wait for reset */ - msleep(MXT_FWRESET_TIME); - - mxt_initialize(data); - mxt_input_dev_create(data); } - enable_irq(data->irq); - - error = mxt_make_highchg(data); - if (error) - return error; - return count; }