Skip to content

Commit

Permalink
Input: cyapa - add gen6 device module support
Browse files Browse the repository at this point in the history
Based on the cyapa core, add support for basic functionality of the gen6
trackpad devices. The driver can automatically determine what protocol
(gen3, gen5, or gen6) should be used with the attached trackpad device.

Signed-off-by: Dudley Du <dudl@cypress.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Dudley Du authored and dtor committed Jul 24, 2015
1 parent 9489761 commit c2c06c4
Show file tree
Hide file tree
Showing 5 changed files with 834 additions and 4 deletions.
2 changes: 1 addition & 1 deletion drivers/input/mouse/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o
obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o
obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o

cyapatp-objs := cyapa.o cyapa_gen3.o cyapa_gen5.o
cyapatp-objs := cyapa.o cyapa_gen3.o cyapa_gen5.o cyapa_gen6.o
psmouse-objs := psmouse-base.o synaptics.o focaltech.o

psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
Expand Down
22 changes: 22 additions & 0 deletions drivers/input/mouse/cyapa.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ static int cyapa_reinitialize(struct cyapa *cyapa);

bool cyapa_is_pip_bl_mode(struct cyapa *cyapa)
{
if (cyapa->gen == CYAPA_GEN6 && cyapa->state == CYAPA_STATE_GEN6_BL)
return true;

if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_BL)
return true;

Expand All @@ -49,6 +52,9 @@ bool cyapa_is_pip_bl_mode(struct cyapa *cyapa)

bool cyapa_is_pip_app_mode(struct cyapa *cyapa)
{
if (cyapa->gen == CYAPA_GEN6 && cyapa->state == CYAPA_STATE_GEN6_APP)
return true;

if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_APP)
return true;

Expand Down Expand Up @@ -204,6 +210,15 @@ static int cyapa_get_state(struct cyapa *cyapa)
if (!error)
goto out_detected;
}
if (cyapa->gen == CYAPA_GEN_UNKNOWN ||
cyapa->gen == CYAPA_GEN6 ||
cyapa->gen == CYAPA_GEN5) {
error = cyapa_pip_state_parse(cyapa,
status, BL_STATUS_SIZE);
if (!error)
goto out_detected;
}
/* For old Gen5 trackpads detecting. */
if ((cyapa->gen == CYAPA_GEN_UNKNOWN ||
cyapa->gen == CYAPA_GEN5) &&
!smbus && even_addr) {
Expand Down Expand Up @@ -300,6 +315,9 @@ static int cyapa_check_is_operational(struct cyapa *cyapa)
return error;

switch (cyapa->gen) {
case CYAPA_GEN6:
cyapa->ops = &cyapa_gen6_ops;
break;
case CYAPA_GEN5:
cyapa->ops = &cyapa_gen5_ops;
break;
Expand Down Expand Up @@ -579,6 +597,8 @@ static int cyapa_initialize(struct cyapa *cyapa)
error = cyapa_gen3_ops.initialize(cyapa);
if (!error)
error = cyapa_gen5_ops.initialize(cyapa);
if (!error)
error = cyapa_gen6_ops.initialize(cyapa);
if (error)
return error;

Expand Down Expand Up @@ -1136,9 +1156,11 @@ static char *cyapa_state_to_string(struct cyapa *cyapa)
case CYAPA_STATE_BL_ACTIVE:
return "bootloader active";
case CYAPA_STATE_GEN5_BL:
case CYAPA_STATE_GEN6_BL:
return "bootloader";
case CYAPA_STATE_OP:
case CYAPA_STATE_GEN5_APP:
case CYAPA_STATE_GEN6_APP:
return "operational"; /* Normal valid state. */
default:
return "invalid mode";
Expand Down
15 changes: 15 additions & 0 deletions drivers/input/mouse/cyapa.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define CYAPA_GEN_UNKNOWN 0x00 /* unknown protocol. */
#define CYAPA_GEN3 0x03 /* support MT-protocol B with tracking ID. */
#define CYAPA_GEN5 0x05 /* support TrueTouch GEN5 trackpad device. */
#define CYAPA_GEN6 0x06 /* support TrueTouch GEN6 trackpad device. */

#define CYAPA_NAME "Cypress APA Trackpad (cyapa)"

Expand Down Expand Up @@ -198,6 +199,9 @@
#define PIP_BL_APP_INFO_RESP_LENGTH 30
#define PIP_BL_GET_INFO_RESP_LENGTH 19

#define PIP_BL_PLATFORM_VER_SHIFT 4
#define PIP_BL_PLATFORM_VER_MASK 0x0f

#define PIP_PRODUCT_FAMILY_MASK 0xf000
#define PIP_PRODUCT_FAMILY_TRACKPAD 0x1000

Expand Down Expand Up @@ -299,6 +303,14 @@ enum cyapa_state {
CYAPA_STATE_OP,
CYAPA_STATE_GEN5_BL,
CYAPA_STATE_GEN5_APP,
CYAPA_STATE_GEN6_BL,
CYAPA_STATE_GEN6_APP,
};

struct gen6_interval_setting {
u16 active_interval;
u16 lp1_interval;
u16 lp2_interval;
};

/* The main device structure */
Expand All @@ -320,9 +332,11 @@ struct cyapa {
u16 runtime_suspend_sleep_time;
u8 dev_pwr_mode;
u16 dev_sleep_time;
struct gen6_interval_setting gen6_interval_setting;

/* Read from query data region. */
char product_id[16];
u8 platform_ver; /* Platform version. */
u8 fw_maj_ver; /* Firmware major version. */
u8 fw_min_ver; /* Firmware minor version. */
u8 btn_capability;
Expand Down Expand Up @@ -411,5 +425,6 @@ extern u8 pip_bl_read_app_info[];
extern const char product_id[];
extern const struct cyapa_dev_ops cyapa_gen3_ops;
extern const struct cyapa_dev_ops cyapa_gen5_ops;
extern const struct cyapa_dev_ops cyapa_gen6_ops;

#endif
69 changes: 66 additions & 3 deletions drivers/input/mouse/cyapa_gen5.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ struct cyapa_pip_touch_record {
* Bit 7 - 3: reserved
* Bit 2 - 0: touch type;
* 0 : standard finger;
* 1 - 15 : reserved.
* 1 : proximity (Start supported in Gen5 TP).
* 2 : finger hover (defined, but not used yet.)
* 3 - 15 : reserved.
*/
u8 touch_type;

Expand Down Expand Up @@ -167,6 +169,9 @@ struct cyapa_pip_touch_record {
* The meaning of this value is different when touch_type is different.
* For standard finger type:
* Touch intensity in counts, pressure value.
* For proximity type (Start supported in Gen5 TP):
* The distance, in surface units, between the contact and
* the surface.
**/
u8 z;

Expand Down Expand Up @@ -218,6 +223,12 @@ struct cyapa_tsg_bin_image_head {
u8 fw_major_version;
u8 fw_minor_version;
u8 fw_revision_control_number[8];
u8 silicon_id_hi;
u8 silicon_id_lo;
u8 chip_revision;
u8 family_id;
u8 bl_ver_maj;
u8 bl_ver_min;
} __packed;

struct cyapa_tsg_bin_image_data_record {
Expand Down Expand Up @@ -1134,6 +1145,39 @@ int cyapa_pip_bl_enter(struct cyapa *cyapa)
cyapa->operational = false;
if (cyapa->gen == CYAPA_GEN5)
cyapa->state = CYAPA_STATE_GEN5_BL;
else if (cyapa->gen == CYAPA_GEN6)
cyapa->state = CYAPA_STATE_GEN6_BL;
return 0;
}

static int cyapa_pip_fw_head_check(struct cyapa *cyapa,
struct cyapa_tsg_bin_image_head *image_head)
{
if (image_head->head_size != 0x0C && image_head->head_size != 0x12)
return -EINVAL;

switch (cyapa->gen) {
case CYAPA_GEN6:
if (image_head->family_id != 0x9B ||
image_head->silicon_id_hi != 0x0B)
return -EINVAL;
break;
case CYAPA_GEN5:
/* Gen5 without proximity support. */
if (cyapa->platform_ver < 2) {
if (image_head->head_size == 0x0C)
break;
return -EINVAL;
}

if (image_head->family_id != 0x91 ||
image_head->silicon_id_hi != 0x02)
return -EINVAL;
break;
default:
return -EINVAL;
}

return 0;
}

Expand All @@ -1150,6 +1194,14 @@ int cyapa_pip_check_fw(struct cyapa *cyapa, const struct firmware *fw)
u16 app_integrity_crc;
int i;

/* Verify the firmware image not miss-used for Gen5 and Gen6. */
if (cyapa_pip_fw_head_check(cyapa,
(struct cyapa_tsg_bin_image_head *)fw->data)) {
dev_err(dev, "%s: firmware image not match TP device.\n",
__func__);
return -EINVAL;
}

image_records =
cyapa_get_image_record_data_num(fw, &flash_records_count);

Expand Down Expand Up @@ -2339,6 +2391,9 @@ static int cyapa_gen5_bl_query_data(struct cyapa *cyapa)
cyapa->fw_maj_ver = resp_data[22];
cyapa->fw_min_ver = resp_data[23];

cyapa->platform_ver = (resp_data[26] >> PIP_BL_PLATFORM_VER_SHIFT) &
PIP_BL_PLATFORM_VER_MASK;

return 0;
}

Expand All @@ -2362,8 +2417,16 @@ static int cyapa_gen5_get_query_data(struct cyapa *cyapa)
PIP_PRODUCT_FAMILY_TRACKPAD)
return -EINVAL;

cyapa->fw_maj_ver = resp_data[15];
cyapa->fw_min_ver = resp_data[16];
cyapa->platform_ver = (resp_data[49] >> PIP_BL_PLATFORM_VER_SHIFT) &
PIP_BL_PLATFORM_VER_MASK;
if (cyapa->gen == CYAPA_GEN5 && cyapa->platform_ver < 2) {
/* Gen5 firmware that does not support proximity. */
cyapa->fw_maj_ver = resp_data[15];
cyapa->fw_min_ver = resp_data[16];
} else {
cyapa->fw_maj_ver = resp_data[9];
cyapa->fw_min_ver = resp_data[10];
}

cyapa->electrodes_x = resp_data[52];
cyapa->electrodes_y = resp_data[53];
Expand Down

0 comments on commit c2c06c4

Please sign in to comment.