[PATCH v18 09/12] input: cyapa: add gen5 trackpad device firmware update function support

2015-01-15 Thread Dudley Du
Add firmware image update function supported for gen5 trackpad device,
it can be used through sysfs update_fw interface.
TEST=test on Chromebooks.

Signed-off-by: Dudley Du 
---
 drivers/input/mouse/Kconfig  |   1 +
 drivers/input/mouse/cyapa_gen5.c | 391 +++
 2 files changed, 392 insertions(+)

diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index d8b46b0..728490e 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -206,6 +206,7 @@ config MOUSE_BCM5974
 config MOUSE_CYAPA
tristate "Cypress APA I2C Trackpad support"
depends on I2C
+   select CRC_ITU_T
help
  This driver adds support for Cypress All Points Addressable (APA)
  I2C Trackpads, including the ones used in 2012 Samsung Chromebooks.
diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
index a049ae3..442b29d 100644
--- a/drivers/input/mouse/cyapa_gen5.c
+++ b/drivers/input/mouse/cyapa_gen5.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "cyapa.h"
 
 
@@ -264,6 +265,79 @@ struct cyapa_gen5_report_data {
struct cyapa_gen5_touch_record touch_records[10];
 } __packed;
 
+struct cyapa_tsg_bin_image_head {
+   u8 head_size;  /* Unit: bytes, including itself. */
+   u8 ttda_driver_major_version;  /* Reserved as 0. */
+   u8 ttda_driver_minor_version;  /* Reserved as 0. */
+   u8 fw_major_version;
+   u8 fw_minor_version;
+   u8 fw_revision_control_number[8];
+} __packed;
+
+struct cyapa_tsg_bin_image_data_record {
+   u8 flash_array_id;
+   __be16 row_number;
+   /* The number of bytes of flash data contained in this record. */
+   __be16 record_len;
+   /* The flash program data. */
+   u8 record_data[CYAPA_TSG_FW_ROW_SIZE];
+} __packed;
+
+struct cyapa_tsg_bin_image {
+   struct cyapa_tsg_bin_image_head image_head;
+   struct cyapa_tsg_bin_image_data_record records[0];
+} __packed;
+
+struct gen5_bl_packet_start {
+   u8 sop;  /* Start of packet, must be 01h */
+   u8 cmd_code;
+   __le16 data_length;  /* Size of data parameter start from data[0] */
+} __packed;
+
+struct gen5_bl_packet_end {
+   __le16 crc;
+   u8 eop;  /* End of packet, must be 17h */
+} __packed;
+
+struct gen5_bl_cmd_head {
+   __le16 addr;   /* Output report register address, must be 0004h */
+   /* Size of packet not including output report register address */
+   __le16 length;
+   u8 report_id;  /* Bootloader output report id, must be 40h */
+   u8 rsvd;  /* Reserved, must be 0 */
+   struct gen5_bl_packet_start packet_start;
+   u8 data[0];  /* Command data variable based on commands */
+} __packed;
+
+/* Initiate bootload command data structure. */
+struct gen5_bl_initiate_cmd_data {
+   /* Key must be "A5h 01h 02h 03h FFh FEh FDh 5Ah" */
+   u8 key[CYAPA_TSG_BL_KEY_SIZE];
+   u8 metadata_raw_parameter[CYAPA_TSG_FLASH_MAP_METADATA_SIZE];
+   __le16 metadata_crc;
+} __packed;
+
+struct gen5_bl_metadata_row_params {
+   __le16 size;
+   __le16 maximun_size;
+   __le32 app_start;
+   __le16 app_len;
+   __le16 app_crc;
+   __le32 app_entry;
+   __le32 upgrade_start;
+   __le16 upgrade_len;
+   __le16 entry_row_crc;
+   u8 padding[36];  /* Padding data must be 0 */
+   __le16 metadata_crc;  /* CRC starts at offset of 60 */
+} __packed;
+
+/* Bootload program and verify row command data structure */
+struct gen5_bl_flash_row_head {
+   u8 flash_array_id;
+   __le16 flash_row_id;
+   u8 flash_data[0];
+} __packed;
+
 struct gen5_app_cmd_head {
__le16 addr;   /* Output report register address, must be 0004h */
/* Size of packet not including output report register address */
@@ -297,6 +371,10 @@ struct gen5_app_get_parameter_data {
 #define GEN5_DEV_UNINIT_SLEEP_TIME(cyapa)  \
(((cyapa)->dev_sleep_time) == UNINIT_SLEEP_TIME)
 
+
+static u8 cyapa_gen5_bl_cmd_key[] = { 0xa5, 0x01, 0x02, 0x03,
+   0xff, 0xfe, 0xfd, 0x5a };
+
 static int cyapa_gen5_initialize(struct cyapa *cyapa)
 {
struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
@@ -618,6 +696,22 @@ static bool cyapa_gen5_sort_tsg_pip_app_resp_data(struct 
cyapa *cyapa,
return false;
 }
 
+static bool cyapa_gen5_sort_application_launch_data(struct cyapa *cyapa,
+   u8 *buf, int len)
+{
+   if (buf == NULL || len < GEN5_RESP_LENGTH_SIZE)
+   return false;
+
+   /*
+* After reset or power on, trackpad device always sets to 0x00 0x00
+* to indicate a reset or power on event.
+*/
+   if (buf[0] == 0 && buf[1] == 0)
+   return true;
+
+   return false;
+}
+
 static bool cyapa_gen5_sort_hid_descriptor_data(struct cyapa *cyapa,
u8 *buf, int len)
 {
@@ -923,6 +1017,80 @@ static int cyapa_gen5_state_parse(struct cyapa 

Re: [PATCH v18 09/12] input: cyapa: add gen5 trackpad device firmware update function support

2015-01-18 Thread Dmitry Torokhov
On Fri, Jan 16, 2015 at 02:34:12PM +0800, Dudley Du wrote:
> + /* APP_INTEGRITY row is always the last row block,
> +  * and the row id must be 0x01ff */
> + row_num = get_unaligned_be16(
> + &image->records[flash_records_count - 1].row_number);
> + if (image->records[flash_records_count - 1].flash_array_id != 0x00 &&
> + row_num != 0x01ff) {

By the way, shouldn't this be "or" and not "and"?

> + dev_err(dev, "%s: invalid app_integrity data.\n", __func__);
> + return -EINVAL;
> + }

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH v18 09/12] input: cyapa: add gen5 trackpad device firmware update function support

2015-01-18 Thread Dudley Du


> -Original Message-
> From: Dmitry Torokhov [mailto:dmitry.torok...@gmail.com]
> Sent: 2015?1?19? 8:27
> To: Dudley Du
> Cc: jmmah...@gmail.com; rydb...@euromail.se; ble...@google.com;
> linux-in...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v18 09/12] input: cyapa: add gen5 trackpad device firmware
> update function support
>
> On Fri, Jan 16, 2015 at 02:34:12PM +0800, Dudley Du wrote:
> > +/* APP_INTEGRITY row is always the last row block,
> > + * and the row id must be 0x01ff */
> > +row_num = get_unaligned_be16(
> > +&image->records[flash_records_count - 1].row_number);
> > +if (image->records[flash_records_count - 1].flash_array_id != 0x00 &&
> > +row_num != 0x01ff) {
>
> By the way, shouldn't this be "or" and not "and"?

It should or, thanks for the correction.

>
> > +dev_err(dev, "%s: invalid app_integrity data.\n", __func__);
> > +return -EINVAL;
> > +}
>
> Thanks.
>
> --
> Dmitry

This message and any attachments may contain Cypress (or its subsidiaries) 
confidential information. If it has been received in error, please advise the 
sender and immediately delete this message.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/