blob: 7caf76cb3d0ed598b502fc37613dab95f2f9e146 [file] [log] [blame]
liuyan451acd62015-01-27 10:03:09 +08001/*
2 * Synaptics DSX touchscreen driver
3 *
4 * Copyright (C) 2012 Synaptics Incorporated
5 *
6 * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
7 * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/slab.h>
22#include <linux/interrupt.h>
Peter Leef2bfbf72016-10-24 11:08:09 +080023#include <linux/mutex.h>
liuyan451acd62015-01-27 10:03:09 +080024#include <linux/delay.h>
25#include <linux/input.h>
26#include <linux/firmware.h>
27#include <linux/platform_device.h>
28#include <linux/input/synaptics_dsx.h>
29#include "synaptics_dsx_core.h"
30
31#define FW_IMAGE_NAME "synaptics/startup_fw_update.img"
wangxl037c0912015-08-11 19:50:06 +080032
liuyan451acd62015-01-27 10:03:09 +080033#define DO_STARTUP_FW_UPDATE
wangxl037c0912015-08-11 19:50:06 +080034
liuyan451acd62015-01-27 10:03:09 +080035#define FORCE_UPDATE false
36#define DO_LOCKDOWN false
37
38#define MAX_IMAGE_NAME_LEN 256
39#define MAX_FIRMWARE_ID_LEN 10
40
41#define IMAGE_HEADER_VERSION_05 0x05
42#define IMAGE_HEADER_VERSION_06 0x06
43#define IMAGE_HEADER_VERSION_10 0x10
44
45#define IMAGE_AREA_OFFSET 0x100
46#define LOCKDOWN_SIZE 0x50
47
48#define V5V6_BOOTLOADER_ID_OFFSET 0
49
50#define V5_PROPERTIES_OFFSET 2
51#define V5_BLOCK_SIZE_OFFSET 3
52#define V5_BLOCK_COUNT_OFFSET 5
53#define V5_BLOCK_NUMBER_OFFSET 0
54#define V5_BLOCK_DATA_OFFSET 2
55
56#define V6_PROPERTIES_OFFSET 1
57#define V6_BLOCK_SIZE_OFFSET 2
58#define V6_BLOCK_COUNT_OFFSET 3
59#define V6_PROPERTIES_2_OFFSET 4
60#define V6_GUEST_CODE_BLOCK_COUNT_OFFSET 5
61#define V6_BLOCK_NUMBER_OFFSET 0
62#define V6_BLOCK_DATA_OFFSET 1
63#define V6_FLASH_COMMAND_OFFSET 2
64#define V6_FLASH_STATUS_OFFSET 3
65
66#define V7_FLASH_STATUS_OFFSET 0
67#define V7_PARTITION_ID_OFFSET 1
68#define V7_BLOCK_NUMBER_OFFSET 2
69#define V7_TRANSFER_LENGTH_OFFSET 3
70#define V7_COMMAND_OFFSET 4
71#define V7_PAYLOAD_OFFSET 5
72
73#define V7_PARTITION_SUPPORT_BYTES 4
74
75#define SLEEP_MODE_NORMAL (0x00)
76#define SLEEP_MODE_SENSOR_SLEEP (0x01)
77#define SLEEP_MODE_RESERVED0 (0x02)
78#define SLEEP_MODE_RESERVED1 (0x03)
79
80#define ENABLE_WAIT_MS (1 * 1000)
81#define WRITE_WAIT_MS (3 * 1000)
82#define ERASE_WAIT_MS (5 * 1000)
83
84#define MIN_SLEEP_TIME_US 50
85#define MAX_SLEEP_TIME_US 100
86
87#define INT_DISABLE_WAIT_MS 20
88#define ENTER_FLASH_PROG_WAIT_MS 20
89
90static int fwu_do_reflash(void);
91
92static ssize_t fwu_sysfs_show_image(struct file *data_file,
93 struct kobject *kobj, struct bin_attribute *attributes,
94 char *buf, loff_t pos, size_t count);
95
96static ssize_t fwu_sysfs_store_image(struct file *data_file,
97 struct kobject *kobj, struct bin_attribute *attributes,
98 char *buf, loff_t pos, size_t count);
99
100static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
101 struct device_attribute *attr, const char *buf, size_t count);
102
103static ssize_t fwu_sysfs_write_config_store(struct device *dev,
104 struct device_attribute *attr, const char *buf, size_t count);
105
106static ssize_t fwu_sysfs_read_config_store(struct device *dev,
107 struct device_attribute *attr, const char *buf, size_t count);
108
109static ssize_t fwu_sysfs_config_area_store(struct device *dev,
110 struct device_attribute *attr, const char *buf, size_t count);
111
112static ssize_t fwu_sysfs_image_name_store(struct device *dev,
113 struct device_attribute *attr, const char *buf, size_t count);
114
115static ssize_t fwu_sysfs_image_size_store(struct device *dev,
116 struct device_attribute *attr, const char *buf, size_t count);
117
118static ssize_t fwu_sysfs_block_size_show(struct device *dev,
119 struct device_attribute *attr, char *buf);
120
121static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
122 struct device_attribute *attr, char *buf);
123
124static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
125 struct device_attribute *attr, char *buf);
126
127static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
128 struct device_attribute *attr, char *buf);
129
130static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
131 struct device_attribute *attr, char *buf);
132
133static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
134 struct device_attribute *attr, char *buf);
135
136static ssize_t fwu_sysfs_guest_code_block_count_show(struct device *dev,
137 struct device_attribute *attr, char *buf);
138
139static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev,
140 struct device_attribute *attr, const char *buf, size_t count);
141
142enum f34_version {
143 F34_V0 = 0,
144 F34_V1,
145 F34_V2,
146};
147
148enum bl_version {
149 BL_V5 = 5,
150 BL_V6 = 6,
151 BL_V7 = 7,
152};
153
154enum flash_area {
155 NONE = 0,
156 UI_FIRMWARE,
157 UI_CONFIG,
158};
159
160enum update_mode {
161 NORMAL = 1,
162 FORCE = 2,
163 LOCKDOWN = 8,
164};
165
166enum config_area {
167 UI_CONFIG_AREA = 0,
168 PM_CONFIG_AREA,
169 BL_CONFIG_AREA,
170 DP_CONFIG_AREA,
171 FLASH_CONFIG_AREA,
172};
173
174enum v7_partition_id {
175 BOOTLOADER_PARTITION = 0x01,
176 DEVICE_CONFIG_PARTITION,
177 FLASH_CONFIG_PARTITION,
178 MANUFACTURING_BLOCK_PARTITION,
179 GUEST_SERIALIZATION_PARTITION,
180 GLOBAL_PARAMETERS_PARTITION,
181 CORE_CODE_PARTITION,
182 CORE_CONFIG_PARTITION,
183 GUEST_CODE_PARTITION,
184 DISPLAY_CONFIG_PARTITION,
185};
186
187enum v7_flash_command {
188 CMD_V7_IDLE = 0x00,
189 CMD_V7_ENTER_BL,
190 CMD_V7_READ,
191 CMD_V7_WRITE,
192 CMD_V7_ERASE,
193 CMD_V7_ERASE_AP,
194 CMD_V7_SENSOR_ID,
195};
196
197enum v5v6_flash_command {
198 CMD_V5V6_IDLE = 0x0,
199 CMD_V5V6_WRITE_FW = 0x2,
200 CMD_V5V6_ERASE_ALL = 0x3,
201 CMD_V5V6_WRITE_LOCKDOWN = 0x4,
202 CMD_V5V6_READ_CONFIG = 0x5,
203 CMD_V5V6_WRITE_CONFIG = 0x6,
204 CMD_V5V6_ERASE_UI_CONFIG = 0x7,
205 CMD_V5V6_ERASE_BL_CONFIG = 0x9,
206 CMD_V5V6_ERASE_DISP_CONFIG = 0xa,
207 CMD_V5V6_ERASE_GUEST_CODE = 0xb,
208 CMD_V5V6_WRITE_GUEST_CODE = 0xc,
209 CMD_V5V6_ENABLE_FLASH_PROG = 0xf,
210};
211
212enum flash_command {
213 CMD_IDLE = 0,
214 CMD_WRITE_FW,
215 CMD_WRITE_CONFIG,
216 CMD_WRITE_LOCKDOWN,
217 CMD_WRITE_GUEST_CODE,
218 CMD_READ_CONFIG,
219 CMD_ERASE_ALL,
220 CMD_ERASE_UI_FIRMWARE,
221 CMD_ERASE_UI_CONFIG,
222 CMD_ERASE_BL_CONFIG,
223 CMD_ERASE_DISP_CONFIG,
224 CMD_ERASE_FLASH_CONFIG,
225 CMD_ERASE_GUEST_CODE,
226 CMD_ENABLE_FLASH_PROG,
227};
228
229enum container_id {
230 TOP_LEVEL_CONTAINER = 0,
231 UI_CONTAINER,
232 UI_CONFIG_CONTAINER,
233 BL_CONTAINER,
234 BL_IMAGE_CONTAINER,
235 BL_CONFIG_CONTAINER,
236 BL_LOCKDOWN_INFO_CONTAINER,
237 PERMANENT_CONFIG_CONTAINER,
238 GUEST_CODE_CONTAINER,
239 BL_PROTOCOL_DESCRIPTOR_CONTAINER,
240 UI_PROTOCOL_DESCRIPTOR_CONTAINER,
241 RMI_SELF_DISCOVERY_CONTAINER,
242 RMI_PAGE_CONTENT_CONTAINER,
243 GENERAL_INFORMATION_CONTAINER,
244 DEVICE_CONFIG_CONTAINER,
245 FLASH_CONFIG_CONTAINER,
246 GUEST_SERIALIZATION_CONTAINER,
247 GLOBAL_PARAMETERS_CONTAINER,
248 CORE_CODE_CONTAINER,
249 CORE_CONFIG_CONTAINER,
250 DISPLAY_CONFIG_CONTAINER,
251};
252
253struct pdt_properties {
254 union {
255 struct {
256 unsigned char reserved_1:6;
257 unsigned char has_bsr:1;
258 unsigned char reserved_2:1;
259 } __packed;
260 unsigned char data[1];
261 };
262};
263
264struct partition_table {
265 unsigned char partition_id:5;
266 unsigned char byte_0_reserved:3;
267 unsigned char byte_1_reserved;
268 unsigned char partition_length_7_0;
269 unsigned char partition_length_15_8;
270 unsigned char start_physical_address_7_0;
271 unsigned char start_physical_address_15_8;
272 unsigned char partition_properties_7_0;
273 unsigned char partition_properties_15_8;
274} __packed;
275
276struct f01_device_control {
277 union {
278 struct {
279 unsigned char sleep_mode:2;
280 unsigned char nosleep:1;
281 unsigned char reserved:2;
282 unsigned char charger_connected:1;
283 unsigned char report_rate:1;
284 unsigned char configured:1;
285 } __packed;
286 unsigned char data[1];
287 };
288};
289
290struct f34_v7_query_0 {
291 union {
292 struct {
293 unsigned char subpacket_1_size:3;
294 unsigned char has_config_id:1;
295 unsigned char f34_query0_b4:1;
296 unsigned char has_thqa:1;
297 unsigned char f34_query0_b6__7:2;
298 } __packed;
299 unsigned char data[1];
300 };
301};
302
303struct f34_v7_query_1_7 {
304 union {
305 struct {
306 /* query 1 */
307 unsigned char bl_minor_revision;
308 unsigned char bl_major_revision;
309
310 /* query 2 */
311 unsigned char bl_fw_id_7_0;
312 unsigned char bl_fw_id_15_8;
313 unsigned char bl_fw_id_23_16;
314 unsigned char bl_fw_id_31_24;
315
316 /* query 3 */
317 unsigned char minimum_write_size;
318 unsigned char block_size_7_0;
319 unsigned char block_size_15_8;
320 unsigned char flash_page_size_7_0;
321 unsigned char flash_page_size_15_8;
322
323 /* query 4 */
324 unsigned char adjustable_partition_area_size_7_0;
325 unsigned char adjustable_partition_area_size_15_8;
326
327 /* query 5 */
328 unsigned char flash_config_length_7_0;
329 unsigned char flash_config_length_15_8;
330
331 /* query 6 */
332 unsigned char payload_length_7_0;
333 unsigned char payload_length_15_8;
334
335 /* query 7 */
336 unsigned char f34_query7_b0:1;
337 unsigned char has_bootloader:1;
338 unsigned char has_device_config:1;
339 unsigned char has_flash_config:1;
340 unsigned char has_manufacturing_block:1;
341 unsigned char has_guest_serialization:1;
342 unsigned char has_global_parameters:1;
343 unsigned char has_core_code:1;
344 unsigned char has_core_config:1;
345 unsigned char has_guest_code:1;
346 unsigned char has_display_config:1;
347 unsigned char f34_query7_b11__15:5;
348 unsigned char f34_query7_b16__23;
349 unsigned char f34_query7_b24__31;
350 } __packed;
351 unsigned char data[21];
352 };
353};
354
355struct f34_v7_data_1_5 {
356 union {
357 struct {
358 unsigned char partition_id:5;
359 unsigned char f34_data1_b5__7:3;
360 unsigned char block_offset_7_0;
361 unsigned char block_offset_15_8;
362 unsigned char transfer_length_7_0;
363 unsigned char transfer_length_15_8;
364 unsigned char command;
365 unsigned char payload_0;
366 unsigned char payload_1;
367 } __packed;
368 unsigned char data[8];
369 };
370};
371
372struct f34_v5v6_flash_properties {
373 union {
374 struct {
375 unsigned char reg_map:1;
376 unsigned char unlocked:1;
377 unsigned char has_config_id:1;
378 unsigned char has_pm_config:1;
379 unsigned char has_bl_config:1;
380 unsigned char has_disp_config:1;
381 unsigned char has_ctrl1:1;
382 unsigned char has_query4:1;
383 } __packed;
384 unsigned char data[1];
385 };
386};
387
388struct f34_v5v6_flash_properties_2 {
389 union {
390 struct {
391 unsigned char has_guest_code:1;
392 unsigned char reserved:7;
393 } __packed;
394 unsigned char data[1];
395 };
396};
397
398struct register_offset {
399 unsigned char properties;
400 unsigned char properties_2;
401 unsigned char block_size;
402 unsigned char block_count;
403 unsigned char gc_block_count;
404 unsigned char flash_status;
405 unsigned char partition_id;
406 unsigned char block_number;
407 unsigned char transfer_length;
408 unsigned char flash_cmd;
409 unsigned char payload;
410};
411
412struct block_count {
413 unsigned short ui_firmware;
414 unsigned short ui_config;
415 unsigned short dp_config;
416 unsigned short fl_config;
417 unsigned short pm_config;
418 unsigned short bl_config;
419 unsigned short lockdown;
420 unsigned short guest_code;
421};
422
423struct physical_address {
424 unsigned short ui_firmware;
425 unsigned short ui_config;
426 unsigned short dp_config;
427 unsigned short guest_code;
428};
429
430struct container_descriptor {
431 unsigned char content_checksum[4];
432 unsigned char container_id[2];
433 unsigned char minor_version;
434 unsigned char major_version;
435 unsigned char reserved_08;
436 unsigned char reserved_09;
437 unsigned char reserved_0a;
438 unsigned char reserved_0b;
439 unsigned char container_option_flags[4];
440 unsigned char content_options_length[4];
441 unsigned char content_options_address[4];
442 unsigned char content_length[4];
443 unsigned char content_address[4];
444};
445
446struct image_header_10 {
447 unsigned char checksum[4];
448 unsigned char reserved_04;
449 unsigned char reserved_05;
450 unsigned char minor_header_version;
451 unsigned char major_header_version;
452 unsigned char reserved_08;
453 unsigned char reserved_09;
454 unsigned char reserved_0a;
455 unsigned char reserved_0b;
456 unsigned char top_level_container_start_addr[4];
457};
458
459struct image_header_05_06 {
460 /* 0x00 - 0x0f */
461 unsigned char checksum[4];
462 unsigned char reserved_04;
463 unsigned char reserved_05;
464 unsigned char options_firmware_id:1;
465 unsigned char options_bootloader:1;
466 unsigned char options_reserved:6;
467 unsigned char header_version;
468 unsigned char firmware_size[4];
469 unsigned char config_size[4];
470 /* 0x10 - 0x1f */
471 unsigned char product_id[PRODUCT_ID_SIZE];
472 unsigned char package_id[2];
473 unsigned char package_id_revision[2];
474 unsigned char product_info[PRODUCT_INFO_SIZE];
475 /* 0x20 - 0x2f */
476 unsigned char bootloader_addr[4];
477 unsigned char bootloader_size[4];
478 unsigned char ui_addr[4];
479 unsigned char ui_size[4];
480 /* 0x30 - 0x3f */
481 unsigned char ds_id[16];
482 /* 0x40 - 0x4f */
483 union {
484 struct {
485 unsigned char cstmr_product_id[PRODUCT_ID_SIZE];
486 unsigned char reserved_4a_4f[6];
487 };
488 struct {
489 unsigned char dsp_cfg_addr[4];
490 unsigned char dsp_cfg_size[4];
491 unsigned char reserved_48_4f[8];
492 };
493 };
494 /* 0x50 - 0x53 */
495 unsigned char firmware_id[4];
496};
497
498struct block_data {
499 unsigned int size;
500 const unsigned char *data;
501};
502
503struct image_metadata {
504 bool contains_firmware_id;
505 bool contains_bootloader;
506 bool contains_disp_config;
507 bool contains_guest_code;
508 bool contains_flash_config;
509 unsigned int firmware_id;
510 unsigned int checksum;
511 unsigned int bootloader_size;
512 unsigned int disp_config_offset;
513 unsigned char bl_version;
514 unsigned char product_id[PRODUCT_ID_SIZE + 1];
515 unsigned char cstmr_product_id[PRODUCT_ID_SIZE + 1];
516 struct block_data bootloader;
517 struct block_data ui_firmware;
518 struct block_data ui_config;
519 struct block_data dp_config;
520 struct block_data fl_config;
521 struct block_data bl_config;
522 struct block_data guest_code;
523 struct block_data lockdown;
524 struct block_count blkcount;
525 struct physical_address phyaddr;
526};
527
528struct synaptics_rmi4_fwu_handle {
529 enum bl_version bl_version;
530 bool initialized;
531 bool in_bl_mode;
532 bool force_update;
533 bool do_lockdown;
534 bool has_guest_code;
535 bool new_partition_table;
536 unsigned int data_pos;
537 unsigned char *ext_data_source;
538 unsigned char *read_config_buf;
539 unsigned char intr_mask;
540 unsigned char command;
541 unsigned char bootloader_id[2];
542 unsigned char flash_status;
543 unsigned char partitions;
544 unsigned short block_size;
545 unsigned short config_size;
546 unsigned short config_area;
547 unsigned short config_block_count;
548 unsigned short flash_config_length;
549 unsigned short payload_length;
550 unsigned short partition_table_bytes;
551 unsigned short read_config_buf_size;
552 const unsigned char *config_data;
553 const unsigned char *image;
554 unsigned char *image_name;
555 unsigned int image_size;
556 struct image_metadata img;
557 struct register_offset off;
558 struct block_count blkcount;
559 struct physical_address phyaddr;
560 struct f34_v5v6_flash_properties flash_properties;
561 struct synaptics_rmi4_fn_desc f34_fd;
562 struct synaptics_rmi4_data *rmi4_data;
563 struct workqueue_struct *fwu_workqueue;
564 struct work_struct fwu_work;
565};
566
567static struct bin_attribute dev_attr_data = {
568 .attr = {
569 .name = "data",
570 .mode = (S_IRUGO | S_IWUGO),
571 },
572 .size = 0,
573 .read = fwu_sysfs_show_image,
574 .write = fwu_sysfs_store_image,
575};
576
577static struct device_attribute attrs[] = {
578 __ATTR(doreflash, S_IWUGO,
579 synaptics_rmi4_show_error,
580 fwu_sysfs_do_reflash_store),
581 __ATTR(writeconfig, S_IWUGO,
582 synaptics_rmi4_show_error,
583 fwu_sysfs_write_config_store),
584 __ATTR(readconfig, S_IWUGO,
585 synaptics_rmi4_show_error,
586 fwu_sysfs_read_config_store),
587 __ATTR(configarea, S_IWUGO,
588 synaptics_rmi4_show_error,
589 fwu_sysfs_config_area_store),
590 __ATTR(imagename, S_IWUGO,
591 synaptics_rmi4_show_error,
592 fwu_sysfs_image_name_store),
593 __ATTR(imagesize, S_IWUGO,
594 synaptics_rmi4_show_error,
595 fwu_sysfs_image_size_store),
596 __ATTR(blocksize, S_IRUGO,
597 fwu_sysfs_block_size_show,
598 synaptics_rmi4_store_error),
599 __ATTR(fwblockcount, S_IRUGO,
600 fwu_sysfs_firmware_block_count_show,
601 synaptics_rmi4_store_error),
602 __ATTR(configblockcount, S_IRUGO,
603 fwu_sysfs_configuration_block_count_show,
604 synaptics_rmi4_store_error),
605 __ATTR(dispconfigblockcount, S_IRUGO,
606 fwu_sysfs_disp_config_block_count_show,
607 synaptics_rmi4_store_error),
608 __ATTR(permconfigblockcount, S_IRUGO,
609 fwu_sysfs_perm_config_block_count_show,
610 synaptics_rmi4_store_error),
611 __ATTR(blconfigblockcount, S_IRUGO,
612 fwu_sysfs_bl_config_block_count_show,
613 synaptics_rmi4_store_error),
614 __ATTR(guestcodeblockcount, S_IRUGO,
615 fwu_sysfs_guest_code_block_count_show,
616 synaptics_rmi4_store_error),
617 __ATTR(writeguestcode, S_IWUGO,
618 synaptics_rmi4_show_error,
619 fwu_sysfs_write_guest_code_store),
620};
621
622static struct synaptics_rmi4_fwu_handle *fwu;
623
624DECLARE_COMPLETION(fwu_remove_complete);
Peter Leef2bfbf72016-10-24 11:08:09 +0800625DEFINE_MUTEX(fwu_sysfs_mutex);
liuyan451acd62015-01-27 10:03:09 +0800626
627static unsigned int le_to_uint(const unsigned char *ptr)
628{
629 return (unsigned int)ptr[0] +
630 (unsigned int)ptr[1] * 0x100 +
631 (unsigned int)ptr[2] * 0x10000 +
632 (unsigned int)ptr[3] * 0x1000000;
633}
634
635static unsigned int be_to_uint(const unsigned char *ptr)
636{
637 return (unsigned int)ptr[3] +
638 (unsigned int)ptr[2] * 0x100 +
639 (unsigned int)ptr[1] * 0x10000 +
640 (unsigned int)ptr[0] * 0x1000000;
641}
642
643static void fwu_compare_partition_tables(void)
644{
645 if (fwu->phyaddr.ui_firmware != fwu->img.phyaddr.ui_firmware) {
646 fwu->new_partition_table = true;
647 return;
648 }
649
650 if (fwu->phyaddr.ui_config != fwu->img.phyaddr.ui_config) {
651 fwu->new_partition_table = true;
652 return;
653 }
654
655 if (fwu->flash_properties.has_disp_config) {
656 if (fwu->phyaddr.dp_config != fwu->img.phyaddr.dp_config) {
657 fwu->new_partition_table = true;
658 return;
659 }
660 }
661
662 if (fwu->flash_properties.has_disp_config) {
663 if (fwu->phyaddr.dp_config != fwu->img.phyaddr.dp_config) {
664 fwu->new_partition_table = true;
665 return;
666 }
667 }
668
669 if (fwu->has_guest_code) {
670 if (fwu->phyaddr.guest_code != fwu->img.phyaddr.guest_code) {
671 fwu->new_partition_table = true;
672 return;
673 }
674 }
675
676 fwu->new_partition_table = false;
677
678 return;
679}
680
681static void fwu_parse_partition_table(const unsigned char *partition_table,
682 struct block_count *blkcount, struct physical_address *phyaddr)
683{
684 unsigned char ii;
685 unsigned char index;
686 unsigned char offset;
687 unsigned short partition_length;
688 unsigned short physical_address;
689 struct partition_table *ptable;
690 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
691
692 for (ii = 0; ii < fwu->partitions; ii++) {
693 index = ii * 8 + 2;
694 ptable = (struct partition_table *)&partition_table[index];
695 partition_length = ptable->partition_length_15_8 << 8 |
696 ptable->partition_length_7_0;
697 physical_address = ptable->start_physical_address_15_8 << 8 |
698 ptable->start_physical_address_7_0;
699 dev_dbg(rmi4_data->pdev->dev.parent,
700 "%s: Partition entry %d:\n",
701 __func__, ii);
702 for (offset = 0; offset < 8; offset++) {
703 dev_dbg(rmi4_data->pdev->dev.parent,
704 "%s: 0x%02x\n",
705 __func__,
706 partition_table[index + offset]);
707 }
708 switch (ptable->partition_id) {
709 case CORE_CODE_PARTITION:
710 blkcount->ui_firmware = partition_length;
711 phyaddr->ui_firmware = physical_address;
712 dev_dbg(rmi4_data->pdev->dev.parent,
713 "%s: Core code block count: %d\n",
714 __func__, blkcount->ui_firmware);
715 break;
716 case CORE_CONFIG_PARTITION:
717 blkcount->ui_config = partition_length;
718 phyaddr->ui_config = physical_address;
719 dev_dbg(rmi4_data->pdev->dev.parent,
720 "%s: Core config block count: %d\n",
721 __func__, blkcount->ui_config);
722 break;
723 case DISPLAY_CONFIG_PARTITION:
724 blkcount->dp_config = partition_length;
725 phyaddr->dp_config = physical_address;
726 dev_dbg(rmi4_data->pdev->dev.parent,
727 "%s: Display config block count: %d\n",
728 __func__, blkcount->dp_config);
729 break;
730 case FLASH_CONFIG_PARTITION:
731 blkcount->fl_config = partition_length;
732 dev_dbg(rmi4_data->pdev->dev.parent,
733 "%s: Flash config block count: %d\n",
734 __func__, blkcount->fl_config);
735 break;
736 case GUEST_CODE_PARTITION:
737 blkcount->guest_code = partition_length;
738 phyaddr->guest_code = physical_address;
739 dev_dbg(rmi4_data->pdev->dev.parent,
740 "%s: Guest code block count: %d\n",
741 __func__, blkcount->guest_code);
742 break;
743 case GUEST_SERIALIZATION_PARTITION:
744 blkcount->pm_config = partition_length;
745 dev_dbg(rmi4_data->pdev->dev.parent,
746 "%s: Guest serialization block count: %d\n",
747 __func__, blkcount->pm_config);
748 break;
749 case GLOBAL_PARAMETERS_PARTITION:
750 blkcount->bl_config = partition_length;
751 dev_dbg(rmi4_data->pdev->dev.parent,
752 "%s: Global parameters block count: %d\n",
753 __func__, blkcount->bl_config);
754 break;
755 case DEVICE_CONFIG_PARTITION:
756 blkcount->lockdown = partition_length;
757 dev_dbg(rmi4_data->pdev->dev.parent,
758 "%s: Device config block count: %d\n",
759 __func__, blkcount->lockdown);
760 break;
761 };
762 }
763
764 return;
765}
766
767static void fwu_parse_image_header_10_bl_container(const unsigned char *image)
768{
769 unsigned char ii;
770 unsigned char num_of_containers;
771 unsigned int addr;
772 unsigned int container_id;
773 unsigned int length;
774 const unsigned char *content;
775 struct container_descriptor *descriptor;
776
777 num_of_containers = (fwu->img.bootloader.size - 4) / 4;
778
779 for (ii = 1; ii <= num_of_containers; ii++) {
780 addr = le_to_uint(fwu->img.bootloader.data + (ii * 4));
781 descriptor = (struct container_descriptor *)(image + addr);
782 container_id = descriptor->container_id[0] |
783 descriptor->container_id[1] << 8;
784 content = image + le_to_uint(descriptor->content_address);
785 length = le_to_uint(descriptor->content_length);
786 switch (container_id) {
787 case BL_CONFIG_CONTAINER:
788 case GLOBAL_PARAMETERS_CONTAINER:
789 fwu->img.bl_config.data = content;
790 fwu->img.bl_config.size = length;
791 break;
792 case BL_LOCKDOWN_INFO_CONTAINER:
793 case DEVICE_CONFIG_CONTAINER:
794 fwu->img.lockdown.data = content;
795 fwu->img.lockdown.size = length;
796 break;
797 default:
798 break;
799 };
800 }
801
802 return;
803}
804
805static void fwu_parse_image_header_10(void)
806{
807 unsigned char ii;
808 unsigned char num_of_containers;
809 unsigned int addr;
810 unsigned int offset;
811 unsigned int container_id;
812 unsigned int length;
813 const unsigned char *image;
814 const unsigned char *content;
815 struct container_descriptor *descriptor;
816 struct image_header_10 *header;
817
818 image = fwu->image;
819 header = (struct image_header_10 *)image;
820
821 fwu->img.checksum = le_to_uint(header->checksum);
822
823 /* address of top level container */
824 offset = le_to_uint(header->top_level_container_start_addr);
825 descriptor = (struct container_descriptor *)(image + offset);
826
827 /* address of top level container content */
828 offset = le_to_uint(descriptor->content_address);
829 num_of_containers = le_to_uint(descriptor->content_length) / 4;
830
831 for (ii = 0; ii < num_of_containers; ii++) {
832 addr = le_to_uint(image + offset);
833 offset += 4;
834 descriptor = (struct container_descriptor *)(image + addr);
835 container_id = descriptor->container_id[0] |
836 descriptor->container_id[1] << 8;
837 content = image + le_to_uint(descriptor->content_address);
838 length = le_to_uint(descriptor->content_length);
839 switch (container_id) {
840 case UI_CONTAINER:
841 case CORE_CODE_CONTAINER:
842 fwu->img.ui_firmware.data = content;
843 fwu->img.ui_firmware.size = length;
844 break;
845 case UI_CONFIG_CONTAINER:
846 case CORE_CONFIG_CONTAINER:
847 fwu->img.ui_config.data = content;
848 fwu->img.ui_config.size = length;
849 break;
850 case BL_CONTAINER:
851 fwu->img.bl_version = *content;
852 fwu->img.bootloader.data = content;
853 fwu->img.bootloader.size = length;
854 fwu_parse_image_header_10_bl_container(image);
855 break;
856 case GUEST_CODE_CONTAINER:
857 fwu->img.contains_guest_code = true;
858 fwu->img.guest_code.data = content;
859 fwu->img.guest_code.size = length;
860 break;
861 case DISPLAY_CONFIG_CONTAINER:
862 fwu->img.contains_disp_config = true;
863 fwu->img.dp_config.data = content;
864 fwu->img.dp_config.size = length;
865 break;
866 case FLASH_CONFIG_CONTAINER:
867 fwu->img.contains_flash_config = true;
868 fwu->img.fl_config.data = content;
869 fwu->img.fl_config.size = length;
870 break;
871 case GENERAL_INFORMATION_CONTAINER:
872 fwu->img.contains_firmware_id = true;
873 fwu->img.firmware_id = le_to_uint(content + 4);
874 break;
875 default:
876 break;
877 }
878 }
879
880 return;
881}
882
883static void fwu_parse_image_header_05_06(void)
884{
885 int retval;
886 const unsigned char *image;
887 struct image_header_05_06 *header;
888 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
889
890 image = fwu->image;
891 header = (struct image_header_05_06 *)image;
892
893 fwu->img.checksum = le_to_uint(header->checksum);
894
895 fwu->img.bl_version = header->header_version;
896
897 fwu->img.ui_firmware.size = le_to_uint(header->firmware_size);
898
899 fwu->img.ui_config.size = le_to_uint(header->config_size);
900
901 fwu->img.contains_firmware_id = header->options_firmware_id;
902 if (fwu->img.contains_firmware_id)
903 fwu->img.firmware_id = le_to_uint(header->firmware_id);
904
905 fwu->img.contains_bootloader = header->options_bootloader;
906 if (fwu->img.contains_bootloader)
907 fwu->img.bootloader_size = le_to_uint(header->bootloader_size);
908
909 if (fwu->img.ui_firmware.size)
910 fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET;
911
912 if (fwu->img.ui_config.size)
913 fwu->img.ui_config.data = image + IMAGE_AREA_OFFSET +
914 fwu->img.ui_firmware.size;
915
916 if (fwu->img.contains_bootloader) {
917 if (fwu->img.ui_firmware.size)
918 fwu->img.ui_firmware.data += fwu->img.bootloader_size;
919 if (fwu->img.ui_config.size)
920 fwu->img.ui_config.data += fwu->img.bootloader_size;
921 }
922
923 if ((fwu->img.bl_version == BL_V5) && fwu->img.contains_bootloader) {
924 fwu->img.contains_disp_config = true;
925 fwu->img.disp_config_offset = le_to_uint(header->dsp_cfg_addr);
926 fwu->img.dp_config.size = le_to_uint(header->dsp_cfg_size);
927 fwu->img.dp_config.data = image + fwu->img.disp_config_offset;
928 } else {
929 fwu->img.contains_disp_config = false;
930 retval = secure_memcpy(fwu->img.cstmr_product_id,
931 sizeof(fwu->img.cstmr_product_id),
932 header->cstmr_product_id,
933 sizeof(header->cstmr_product_id),
934 PRODUCT_ID_SIZE);
935 if (retval < 0) {
936 dev_err(rmi4_data->pdev->dev.parent,
937 "%s: Failed to copy custom product ID string\n",
938 __func__);
939 }
940 fwu->img.cstmr_product_id[PRODUCT_ID_SIZE] = 0;
941 }
942
943 retval = secure_memcpy(fwu->img.product_id,
944 sizeof(fwu->img.product_id),
945 header->product_id,
946 sizeof(header->product_id),
947 PRODUCT_ID_SIZE);
948 if (retval < 0) {
949 dev_err(rmi4_data->pdev->dev.parent,
950 "%s: Failed to copy product ID string\n",
951 __func__);
952 }
953 fwu->img.product_id[PRODUCT_ID_SIZE] = 0;
954
955 fwu->img.lockdown.size = LOCKDOWN_SIZE;
956 fwu->img.lockdown.data = image + IMAGE_AREA_OFFSET - LOCKDOWN_SIZE;
957
958 return;
959}
960
961static int fwu_parse_image_info(void)
962{
963 struct image_header_10 *header;
964 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
965
966 header = (struct image_header_10 *)fwu->image;
967
968 memset(&fwu->img, 0x00, sizeof(fwu->img));
969
970 switch (header->major_header_version) {
971 case IMAGE_HEADER_VERSION_10:
972 fwu_parse_image_header_10();
973 break;
974 case IMAGE_HEADER_VERSION_05:
975 case IMAGE_HEADER_VERSION_06:
976 fwu_parse_image_header_05_06();
977 break;
978 default:
979 dev_err(rmi4_data->pdev->dev.parent,
980 "%s: Unsupported image file format (0x%02x)\n",
981 __func__, header->major_header_version);
982 return -EINVAL;
983 }
984
985 if (fwu->bl_version == BL_V7) {
986 if (!fwu->img.contains_flash_config) {
987 dev_err(rmi4_data->pdev->dev.parent,
988 "%s: No flash config found in firmware image\n",
989 __func__);
990 return -EINVAL;
991 }
992
993 fwu_parse_partition_table(fwu->img.fl_config.data,
994 &fwu->img.blkcount, &fwu->img.phyaddr);
995
996 fwu_compare_partition_tables();
997 } else {
998 fwu->new_partition_table = false;
999 }
1000
1001 return 0;
1002}
1003
1004static int fwu_read_flash_status(void)
1005{
1006 int retval;
1007 unsigned char status;
1008 unsigned char command;
1009 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1010
1011 retval = synaptics_rmi4_reg_read(rmi4_data,
1012 fwu->f34_fd.data_base_addr + fwu->off.flash_status,
1013 &status,
1014 sizeof(status));
1015 if (retval < 0) {
1016 dev_err(rmi4_data->pdev->dev.parent,
1017 "%s: Failed to read flash status\n",
1018 __func__);
1019 return retval;
1020 }
1021
1022 fwu->in_bl_mode = status >> 7;
1023
1024 if (fwu->bl_version == BL_V5)
1025 fwu->flash_status = (status >> 4) & MASK_3BIT;
1026 else if (fwu->bl_version == BL_V6)
1027 fwu->flash_status = status & MASK_3BIT;
1028 else if (fwu->bl_version == BL_V7)
1029 fwu->flash_status = status & MASK_5BIT;
1030
1031 if (fwu->flash_status != 0x00) {
1032 dev_err(rmi4_data->pdev->dev.parent,
1033 "%s: Flash status = %d, command = 0x%02x\n",
1034 __func__, fwu->flash_status, fwu->command);
1035 }
1036
1037 retval = synaptics_rmi4_reg_read(rmi4_data,
1038 fwu->f34_fd.data_base_addr + fwu->off.flash_cmd,
1039 &command,
1040 sizeof(command));
1041 if (retval < 0) {
1042 dev_err(rmi4_data->pdev->dev.parent,
1043 "%s: Failed to read flash command\n",
1044 __func__);
1045 return retval;
1046 }
1047
1048 if (fwu->bl_version == BL_V5)
1049 fwu->command = command & MASK_4BIT;
1050 else if (fwu->bl_version == BL_V6)
1051 fwu->command = command & MASK_6BIT;
1052 else if (fwu->bl_version == BL_V7)
1053 fwu->command = command;
1054
1055 return 0;
1056}
1057
1058static int fwu_wait_for_idle(int timeout_ms, bool poll)
1059{
1060 int count = 0;
1061 int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1;
1062 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1063
1064 do {
1065 usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US);
1066
1067 count++;
1068 if (poll || (count == timeout_count))
1069 fwu_read_flash_status();
1070
1071 if ((fwu->command == CMD_IDLE) && (fwu->flash_status == 0x00))
1072 return 0;
1073 } while (count < timeout_count);
1074
1075 dev_err(rmi4_data->pdev->dev.parent,
1076 "%s: Timed out waiting for idle status\n",
1077 __func__);
1078
1079 return -ETIMEDOUT;
1080}
1081
1082static int fwu_write_f34_v7_command_single_transaction(unsigned char cmd)
1083{
1084 int retval;
1085 unsigned char base;
1086 struct f34_v7_data_1_5 data_1_5;
1087 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1088
1089 base = fwu->f34_fd.data_base_addr;
1090
1091 memset(data_1_5.data, 0x00, sizeof(data_1_5.data));
1092
1093 switch (cmd) {
1094 case CMD_ERASE_ALL:
1095 data_1_5.partition_id = CORE_CODE_PARTITION;
1096 data_1_5.command = CMD_V7_ERASE_AP;
1097 break;
1098 case CMD_ERASE_UI_FIRMWARE:
1099 data_1_5.partition_id = CORE_CODE_PARTITION;
1100 data_1_5.command = CMD_V7_ERASE;
1101 break;
1102 case CMD_ERASE_BL_CONFIG:
1103 data_1_5.partition_id = GLOBAL_PARAMETERS_PARTITION;
1104 data_1_5.command = CMD_V7_ERASE;
1105 break;
1106 case CMD_ERASE_UI_CONFIG:
1107 data_1_5.partition_id = CORE_CONFIG_PARTITION;
1108 data_1_5.command = CMD_V7_ERASE;
1109 break;
1110 case CMD_ERASE_DISP_CONFIG:
1111 data_1_5.partition_id = DISPLAY_CONFIG_PARTITION;
1112 data_1_5.command = CMD_V7_ERASE;
1113 break;
1114 case CMD_ERASE_FLASH_CONFIG:
1115 data_1_5.partition_id = FLASH_CONFIG_PARTITION;
1116 data_1_5.command = CMD_V7_ERASE;
1117 break;
1118 case CMD_ERASE_GUEST_CODE:
1119 data_1_5.partition_id = GUEST_CODE_PARTITION;
1120 data_1_5.command = CMD_V7_ERASE;
1121 break;
1122 case CMD_ENABLE_FLASH_PROG:
1123 data_1_5.partition_id = BOOTLOADER_PARTITION;
1124 data_1_5.command = CMD_V7_ENTER_BL;
1125 break;
1126 };
1127
1128 data_1_5.payload_0 = fwu->bootloader_id[0];
1129 data_1_5.payload_1 = fwu->bootloader_id[1];
1130
1131 retval = synaptics_rmi4_reg_write(rmi4_data,
1132 base + fwu->off.partition_id,
1133 data_1_5.data,
1134 sizeof(data_1_5.data));
1135 if (retval < 0) {
1136 dev_err(rmi4_data->pdev->dev.parent,
1137 "%s: Failed to write single transaction command\n",
1138 __func__);
1139 return retval;
1140 }
1141
1142 return 0;
1143}
1144
1145static int fwu_write_f34_v7_command(unsigned char cmd)
1146{
1147 int retval;
1148 unsigned char base;
1149 unsigned char command;
1150 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1151
1152 base = fwu->f34_fd.data_base_addr;
1153
1154 switch (cmd) {
1155 case CMD_WRITE_FW:
1156 case CMD_WRITE_CONFIG:
1157 case CMD_WRITE_GUEST_CODE:
1158 command = CMD_V7_WRITE;
1159 break;
1160 case CMD_READ_CONFIG:
1161 command = CMD_V7_READ;
1162 break;
1163 case CMD_ERASE_ALL:
1164 command = CMD_V7_ERASE_AP;
1165 break;
1166 case CMD_ERASE_UI_FIRMWARE:
1167 case CMD_ERASE_BL_CONFIG:
1168 case CMD_ERASE_UI_CONFIG:
1169 case CMD_ERASE_DISP_CONFIG:
1170 case CMD_ERASE_FLASH_CONFIG:
1171 case CMD_ERASE_GUEST_CODE:
1172 command = CMD_V7_ERASE;
1173 break;
1174 case CMD_ENABLE_FLASH_PROG:
1175 command = CMD_V7_ENTER_BL;
1176 break;
1177 default:
1178 dev_err(rmi4_data->pdev->dev.parent,
1179 "%s: Invalid command 0x%02x\n",
1180 __func__, cmd);
1181 return -EINVAL;
1182 };
1183
1184 fwu->command = command;
1185
1186 switch (cmd) {
1187 case CMD_ERASE_ALL:
1188 case CMD_ERASE_UI_FIRMWARE:
1189 case CMD_ERASE_BL_CONFIG:
1190 case CMD_ERASE_UI_CONFIG:
1191 case CMD_ERASE_DISP_CONFIG:
1192 case CMD_ERASE_FLASH_CONFIG:
1193 case CMD_ERASE_GUEST_CODE:
1194 case CMD_ENABLE_FLASH_PROG:
1195 retval = fwu_write_f34_v7_command_single_transaction(cmd);
1196 if (retval < 0)
1197 return retval;
1198 else
1199 return 0;
1200 default:
1201 break;
1202 };
1203
1204 retval = synaptics_rmi4_reg_write(rmi4_data,
1205 base + fwu->off.flash_cmd,
1206 &command,
1207 sizeof(command));
1208 if (retval < 0) {
1209 dev_err(rmi4_data->pdev->dev.parent,
1210 "%s: Failed to write flash command\n",
1211 __func__);
1212 return retval;
1213 }
1214
1215 return 0;
1216}
1217
1218static int fwu_write_f34_v5v6_command(unsigned char cmd)
1219{
1220 int retval;
1221 unsigned char base;
1222 unsigned char command;
1223 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1224
1225 base = fwu->f34_fd.data_base_addr;
1226
1227 switch (cmd) {
1228 case CMD_IDLE:
1229 command = CMD_V5V6_IDLE;
1230 break;
1231 case CMD_WRITE_FW:
1232 command = CMD_V5V6_WRITE_FW;
1233 break;
1234 case CMD_WRITE_CONFIG:
1235 command = CMD_V5V6_WRITE_CONFIG;
1236 break;
1237 case CMD_WRITE_LOCKDOWN:
1238 command = CMD_V5V6_WRITE_LOCKDOWN;
1239 break;
1240 case CMD_WRITE_GUEST_CODE:
1241 command = CMD_V5V6_WRITE_GUEST_CODE;
1242 break;
1243 case CMD_READ_CONFIG:
1244 command = CMD_V5V6_READ_CONFIG;
1245 break;
1246 case CMD_ERASE_ALL:
1247 command = CMD_V5V6_ERASE_ALL;
1248 break;
1249 case CMD_ERASE_UI_CONFIG:
1250 command = CMD_V5V6_ERASE_UI_CONFIG;
1251 break;
1252 case CMD_ERASE_DISP_CONFIG:
1253 command = CMD_V5V6_ERASE_DISP_CONFIG;
1254 break;
1255 case CMD_ERASE_GUEST_CODE:
1256 command = CMD_V5V6_ERASE_GUEST_CODE;
1257 break;
1258 case CMD_ENABLE_FLASH_PROG:
1259 command = CMD_V5V6_ENABLE_FLASH_PROG;
1260 break;
1261 default:
1262 dev_err(rmi4_data->pdev->dev.parent,
1263 "%s: Invalid command 0x%02x\n",
1264 __func__, cmd);
1265 return -EINVAL;
1266 }
1267
1268 switch (cmd) {
1269 case CMD_ERASE_ALL:
1270 case CMD_ERASE_UI_CONFIG:
1271 case CMD_ERASE_DISP_CONFIG:
1272 case CMD_ERASE_GUEST_CODE:
1273 case CMD_ENABLE_FLASH_PROG:
1274 retval = synaptics_rmi4_reg_write(rmi4_data,
1275 base + fwu->off.payload,
1276 fwu->bootloader_id,
1277 sizeof(fwu->bootloader_id));
1278 if (retval < 0) {
1279 dev_err(rmi4_data->pdev->dev.parent,
1280 "%s: Failed to write bootloader ID\n",
1281 __func__);
1282 return retval;
1283 }
1284 break;
1285 default:
1286 break;
1287 };
1288
1289 fwu->command = command;
1290
1291 retval = synaptics_rmi4_reg_write(rmi4_data,
1292 base + fwu->off.flash_cmd,
1293 &command,
1294 sizeof(command));
1295 if (retval < 0) {
1296 dev_err(rmi4_data->pdev->dev.parent,
1297 "%s: Failed to write command 0x%02x\n",
1298 __func__, command);
1299 return retval;
1300 }
1301
1302 return 0;
1303}
1304
1305static int fwu_write_f34_command(unsigned char cmd)
1306{
1307 int retval;
1308
1309 if (fwu->bl_version == BL_V7)
1310 retval = fwu_write_f34_v7_command(cmd);
1311 else
1312 retval = fwu_write_f34_v5v6_command(cmd);
1313
1314 return retval;
1315}
1316
1317static int fwu_write_f34_v7_partition_id(unsigned char cmd)
1318{
1319 int retval;
1320 unsigned char base;
1321 unsigned char partition;
1322 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1323
1324 base = fwu->f34_fd.data_base_addr;
1325
1326 switch (cmd) {
1327 case CMD_WRITE_FW:
1328 partition = CORE_CODE_PARTITION;
1329 break;
1330 case CMD_WRITE_CONFIG:
1331 case CMD_READ_CONFIG:
1332 if (fwu->config_area == UI_CONFIG_AREA)
1333 partition = CORE_CONFIG_PARTITION;
1334 else if (fwu->config_area == DP_CONFIG_AREA)
1335 partition = DISPLAY_CONFIG_PARTITION;
1336 else if (fwu->config_area == PM_CONFIG_AREA)
1337 partition = GUEST_SERIALIZATION_PARTITION;
1338 else if (fwu->config_area == BL_CONFIG_AREA)
1339 partition = GLOBAL_PARAMETERS_PARTITION;
1340 else if (fwu->config_area == FLASH_CONFIG_AREA)
1341 partition = FLASH_CONFIG_PARTITION;
1342 break;
1343 case CMD_WRITE_GUEST_CODE:
1344 partition = GUEST_CODE_PARTITION;
1345 break;
1346 case CMD_ERASE_ALL:
1347 partition = CORE_CODE_PARTITION;
1348 break;
1349 case CMD_ERASE_BL_CONFIG:
1350 partition = GLOBAL_PARAMETERS_PARTITION;
1351 break;
1352 case CMD_ERASE_UI_CONFIG:
1353 partition = CORE_CONFIG_PARTITION;
1354 break;
1355 case CMD_ERASE_DISP_CONFIG:
1356 partition = DISPLAY_CONFIG_PARTITION;
1357 break;
1358 case CMD_ERASE_FLASH_CONFIG:
1359 partition = FLASH_CONFIG_PARTITION;
1360 break;
1361 case CMD_ERASE_GUEST_CODE:
1362 partition = GUEST_CODE_PARTITION;
1363 break;
1364 case CMD_ENABLE_FLASH_PROG:
1365 partition = BOOTLOADER_PARTITION;
1366 break;
1367 default:
1368 dev_err(rmi4_data->pdev->dev.parent,
1369 "%s: Invalid command 0x%02x\n",
1370 __func__, cmd);
1371 return -EINVAL;
1372 };
1373
1374 retval = synaptics_rmi4_reg_write(rmi4_data,
1375 base + fwu->off.partition_id,
1376 &partition,
1377 sizeof(partition));
1378 if (retval < 0) {
1379 dev_err(rmi4_data->pdev->dev.parent,
1380 "%s: Failed to write partition ID\n",
1381 __func__);
1382 return retval;
1383 }
1384
1385 return 0;
1386}
1387
1388static int fwu_write_f34_partition_id(unsigned char cmd)
1389{
1390 int retval;
1391
1392 if (fwu->bl_version == BL_V7)
1393 retval = fwu_write_f34_v7_partition_id(cmd);
1394 else
1395 retval = 0;
1396
1397 return retval;
1398}
1399
1400static int fwu_read_f34_v7_partition_table(void)
1401{
1402 int retval;
1403 unsigned char base;
1404 unsigned char length[2];
1405 unsigned short block_number = 0;
1406 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1407
1408 base = fwu->f34_fd.data_base_addr;
1409
1410 fwu->config_area = FLASH_CONFIG_AREA;
1411
1412 retval = fwu_write_f34_partition_id(CMD_READ_CONFIG);
1413 if (retval < 0)
1414 return retval;
1415
1416 retval = synaptics_rmi4_reg_write(rmi4_data,
1417 base + fwu->off.block_number,
1418 (unsigned char *)&block_number,
1419 sizeof(block_number));
1420 if (retval < 0) {
1421 dev_err(rmi4_data->pdev->dev.parent,
1422 "%s: Failed to write block number\n",
1423 __func__);
1424 return retval;
1425 }
1426
1427 length[0] = (unsigned char)(fwu->flash_config_length & MASK_8BIT);
1428 length[1] = (unsigned char)(fwu->flash_config_length >> 8);
1429
1430 retval = synaptics_rmi4_reg_write(rmi4_data,
1431 base + fwu->off.transfer_length,
1432 length,
1433 sizeof(length));
1434 if (retval < 0) {
1435 dev_err(rmi4_data->pdev->dev.parent,
1436 "%s: Failed to write transfer length\n",
1437 __func__);
1438 return retval;
1439 }
1440
1441 retval = fwu_write_f34_command(CMD_READ_CONFIG);
1442 if (retval < 0) {
1443 dev_err(rmi4_data->pdev->dev.parent,
1444 "%s: Failed to write command\n",
1445 __func__);
1446 return retval;
1447 }
1448
1449 retval = fwu_wait_for_idle(WRITE_WAIT_MS, true);
1450 if (retval < 0) {
1451 dev_err(rmi4_data->pdev->dev.parent,
1452 "%s: Failed to wait for idle status\n",
1453 __func__);
1454 return retval;
1455 }
1456
1457 retval = synaptics_rmi4_reg_read(rmi4_data,
1458 base + fwu->off.payload,
1459 fwu->read_config_buf,
1460 fwu->partition_table_bytes);
1461 if (retval < 0) {
1462 dev_err(rmi4_data->pdev->dev.parent,
1463 "%s: Failed to read block data\n",
1464 __func__);
1465 return retval;
1466 }
1467
1468 return 0;
1469}
1470
1471static int fwu_read_f34_v7_queries(void)
1472{
1473 int retval;
1474 unsigned char ii;
1475 unsigned char base;
1476 unsigned char index;
1477 unsigned char offset;
1478 unsigned char *ptable;
1479 struct f34_v7_query_0 query_0;
1480 struct f34_v7_query_1_7 query_1_7;
1481 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1482
1483 base = fwu->f34_fd.query_base_addr;
1484
1485 retval = synaptics_rmi4_reg_read(rmi4_data,
1486 base,
1487 query_0.data,
1488 sizeof(query_0.data));
1489 if (retval < 0) {
1490 dev_err(rmi4_data->pdev->dev.parent,
1491 "%s: Failed to read query 0\n",
1492 __func__);
1493 return retval;
1494 }
1495
1496 offset = query_0.subpacket_1_size + 1;
1497
1498 retval = synaptics_rmi4_reg_read(rmi4_data,
1499 base + offset,
1500 query_1_7.data,
1501 sizeof(query_1_7.data));
1502 if (retval < 0) {
1503 dev_err(rmi4_data->pdev->dev.parent,
1504 "%s: Failed to read queries 1 to 7\n",
1505 __func__);
1506 return retval;
1507 }
1508
1509 fwu->bootloader_id[0] = query_1_7.bl_minor_revision;
1510 fwu->bootloader_id[1] = query_1_7.bl_major_revision;
1511
1512 fwu->block_size = query_1_7.block_size_15_8 << 8 |
1513 query_1_7.block_size_7_0;
1514
1515 fwu->flash_config_length = query_1_7.flash_config_length_15_8 << 8 |
1516 query_1_7.flash_config_length_7_0;
1517
1518 fwu->payload_length = query_1_7.payload_length_15_8 << 8 |
1519 query_1_7.payload_length_7_0;
1520
1521 fwu->off.flash_status = V7_FLASH_STATUS_OFFSET;
1522 fwu->off.partition_id = V7_PARTITION_ID_OFFSET;
1523 fwu->off.block_number = V7_BLOCK_NUMBER_OFFSET;
1524 fwu->off.transfer_length = V7_TRANSFER_LENGTH_OFFSET;
1525 fwu->off.flash_cmd = V7_COMMAND_OFFSET;
1526 fwu->off.payload = V7_PAYLOAD_OFFSET;
1527
1528 fwu->flash_properties.has_disp_config = query_1_7.has_display_config;
1529 fwu->flash_properties.has_pm_config = query_1_7.has_guest_serialization;
1530 fwu->flash_properties.has_bl_config = query_1_7.has_global_parameters;
1531
1532 fwu->has_guest_code = query_1_7.has_guest_code;
1533
1534 index = sizeof(query_1_7.data) - V7_PARTITION_SUPPORT_BYTES;
1535
1536 fwu->partitions = 0;
1537 for (offset = 0; offset < V7_PARTITION_SUPPORT_BYTES; offset++) {
1538 for (ii = 0; ii < 8; ii++) {
1539 if (query_1_7.data[index + offset] & (1 << ii))
1540 fwu->partitions++;
1541 }
1542
1543 dev_dbg(rmi4_data->pdev->dev.parent,
1544 "%s: Supported partitions: 0x%02x\n",
1545 __func__, query_1_7.data[index + offset]);
1546 }
1547
1548 fwu->partition_table_bytes = fwu->partitions * 8 + 2;
1549
1550 kfree(fwu->read_config_buf);
1551 fwu->read_config_buf = kzalloc(fwu->partition_table_bytes, GFP_KERNEL);
1552 if (!fwu->read_config_buf) {
1553 dev_err(rmi4_data->pdev->dev.parent,
1554 "%s: Failed to alloc mem for fwu->read_config_buf\n",
1555 __func__);
1556 fwu->read_config_buf_size = 0;
1557 return -ENOMEM;
1558 }
1559 fwu->read_config_buf_size = fwu->partition_table_bytes;
1560 ptable = fwu->read_config_buf;
1561
1562 retval = fwu_read_f34_v7_partition_table();
1563 if (retval < 0) {
1564 dev_err(rmi4_data->pdev->dev.parent,
1565 "%s: Failed to read partition table\n",
1566 __func__);
1567 return retval;
1568 }
1569
1570 fwu_parse_partition_table(ptable, &fwu->blkcount, &fwu->phyaddr);
1571
1572 return 0;
1573}
1574
1575static int fwu_read_f34_v5v6_queries(void)
1576{
1577 int retval;
1578 unsigned char count;
1579 unsigned char base;
1580 unsigned char buf[10];
1581 struct f34_v5v6_flash_properties_2 properties_2;
1582 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1583
1584 base = fwu->f34_fd.query_base_addr;
1585
1586 retval = synaptics_rmi4_reg_read(rmi4_data,
1587 base + V5V6_BOOTLOADER_ID_OFFSET,
1588 fwu->bootloader_id,
1589 sizeof(fwu->bootloader_id));
1590 if (retval < 0) {
1591 dev_err(rmi4_data->pdev->dev.parent,
1592 "%s: Failed to read bootloader ID\n",
1593 __func__);
1594 return retval;
1595 }
1596
1597 if (fwu->bl_version == BL_V5) {
1598 fwu->off.properties = V5_PROPERTIES_OFFSET;
1599 fwu->off.block_size = V5_BLOCK_SIZE_OFFSET;
1600 fwu->off.block_count = V5_BLOCK_COUNT_OFFSET;
1601 fwu->off.block_number = V5_BLOCK_NUMBER_OFFSET;
1602 fwu->off.payload = V5_BLOCK_DATA_OFFSET;
1603 } else if (fwu->bl_version == BL_V6) {
1604 fwu->off.properties = V6_PROPERTIES_OFFSET;
1605 fwu->off.properties_2 = V6_PROPERTIES_2_OFFSET;
1606 fwu->off.block_size = V6_BLOCK_SIZE_OFFSET;
1607 fwu->off.block_count = V6_BLOCK_COUNT_OFFSET;
1608 fwu->off.gc_block_count = V6_GUEST_CODE_BLOCK_COUNT_OFFSET;
1609 fwu->off.block_number = V6_BLOCK_NUMBER_OFFSET;
1610 fwu->off.payload = V6_BLOCK_DATA_OFFSET;
1611 }
1612
1613 retval = synaptics_rmi4_reg_read(rmi4_data,
1614 base + fwu->off.block_size,
1615 buf,
1616 2);
1617 if (retval < 0) {
1618 dev_err(rmi4_data->pdev->dev.parent,
1619 "%s: Failed to read block size info\n",
1620 __func__);
1621 return retval;
1622 }
1623
1624 batohs(&fwu->block_size, &(buf[0]));
1625
1626 if (fwu->bl_version == BL_V5) {
1627 fwu->off.flash_cmd = fwu->off.payload + fwu->block_size;
1628 fwu->off.flash_status = fwu->off.flash_cmd;
1629 } else if (fwu->bl_version == BL_V6) {
1630 fwu->off.flash_cmd = V6_FLASH_COMMAND_OFFSET;
1631 fwu->off.flash_status = V6_FLASH_STATUS_OFFSET;
1632 }
1633
1634 retval = synaptics_rmi4_reg_read(rmi4_data,
1635 base + fwu->off.properties,
1636 fwu->flash_properties.data,
1637 sizeof(fwu->flash_properties.data));
1638 if (retval < 0) {
1639 dev_err(rmi4_data->pdev->dev.parent,
1640 "%s: Failed to read flash properties\n",
1641 __func__);
1642 return retval;
1643 }
1644
1645 count = 4;
1646
1647 if (fwu->flash_properties.has_pm_config)
1648 count += 2;
1649
1650 if (fwu->flash_properties.has_bl_config)
1651 count += 2;
1652
1653 if (fwu->flash_properties.has_disp_config)
1654 count += 2;
1655
1656 retval = synaptics_rmi4_reg_read(rmi4_data,
1657 base + fwu->off.block_count,
1658 buf,
1659 count);
1660 if (retval < 0) {
1661 dev_err(rmi4_data->pdev->dev.parent,
1662 "%s: Failed to read block count info\n",
1663 __func__);
1664 return retval;
1665 }
1666
1667 batohs(&fwu->blkcount.ui_firmware, &(buf[0]));
1668 batohs(&fwu->blkcount.ui_config, &(buf[2]));
1669
1670 count = 4;
1671
1672 if (fwu->flash_properties.has_pm_config) {
1673 batohs(&fwu->blkcount.pm_config, &(buf[count]));
1674 count += 2;
1675 }
1676
1677 if (fwu->flash_properties.has_bl_config) {
1678 batohs(&fwu->blkcount.bl_config, &(buf[count]));
1679 count += 2;
1680 }
1681
1682 if (fwu->flash_properties.has_disp_config)
1683 batohs(&fwu->blkcount.dp_config, &(buf[count]));
1684
1685 fwu->has_guest_code = false;
1686
1687 if (fwu->flash_properties.has_query4) {
1688 retval = synaptics_rmi4_reg_read(rmi4_data,
1689 base + fwu->off.properties_2,
1690 properties_2.data,
1691 sizeof(properties_2.data));
1692 if (retval < 0) {
1693 dev_err(rmi4_data->pdev->dev.parent,
1694 "%s: Failed to read flash properties 2\n",
1695 __func__);
1696 return retval;
1697 }
1698
1699 if (properties_2.has_guest_code) {
1700 retval = synaptics_rmi4_reg_read(rmi4_data,
1701 base + fwu->off.gc_block_count,
1702 buf,
1703 2);
1704 if (retval < 0) {
1705 dev_err(rmi4_data->pdev->dev.parent,
1706 "%s: Failed to read guest code block count\n",
1707 __func__);
1708 return retval;
1709 }
1710
1711 batohs(&fwu->blkcount.guest_code, &(buf[0]));
1712 fwu->has_guest_code = true;
1713 }
1714 }
1715
1716 return 0;
1717}
1718
1719static int fwu_read_f34_queries(void)
1720{
1721 int retval;
1722
1723 memset(&fwu->blkcount, 0x00, sizeof(fwu->blkcount));
1724 memset(&fwu->phyaddr, 0x00, sizeof(fwu->phyaddr));
1725
1726 if (fwu->bl_version == BL_V7)
1727 retval = fwu_read_f34_v7_queries();
1728 else
1729 retval = fwu_read_f34_v5v6_queries();
1730
1731 return retval;
1732}
1733
1734static int fwu_write_f34_v7_blocks(unsigned char *block_ptr,
1735 unsigned short block_cnt, unsigned char command)
1736{
1737 int retval;
1738 unsigned char base;
1739 unsigned char length[2];
1740 unsigned short transfer;
1741 unsigned short max_transfer;
1742 unsigned short remaining = block_cnt;
1743 unsigned short block_number = 0;
1744 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1745
1746 base = fwu->f34_fd.data_base_addr;
1747
1748 retval = fwu_write_f34_partition_id(command);
1749 if (retval < 0)
1750 return retval;
1751
1752 retval = synaptics_rmi4_reg_write(rmi4_data,
1753 base + fwu->off.block_number,
1754 (unsigned char *)&block_number,
1755 sizeof(block_number));
1756 if (retval < 0) {
1757 dev_err(rmi4_data->pdev->dev.parent,
1758 "%s: Failed to write block number\n",
1759 __func__);
1760 return retval;
1761 }
1762
1763 if (fwu->payload_length > (PAGE_SIZE / fwu->block_size))
1764 max_transfer = PAGE_SIZE / fwu->block_size;
1765 else
1766 max_transfer = fwu->payload_length;
1767
1768 do {
1769 if (remaining / max_transfer)
1770 transfer = max_transfer;
1771 else
1772 transfer = remaining;
1773
1774 length[0] = (unsigned char)(transfer & MASK_8BIT);
1775 length[1] = (unsigned char)(transfer >> 8);
1776
1777 retval = synaptics_rmi4_reg_write(rmi4_data,
1778 base + fwu->off.transfer_length,
1779 length,
1780 sizeof(length));
1781 if (retval < 0) {
1782 dev_err(rmi4_data->pdev->dev.parent,
1783 "%s: Failed to write transfer length (%d blocks remaining)\n",
1784 __func__, remaining);
1785 return retval;
1786 }
1787
1788 retval = fwu_write_f34_command(command);
1789 if (retval < 0) {
1790 dev_err(rmi4_data->pdev->dev.parent,
1791 "%s: Failed to write command (%d blocks remaining)\n",
1792 __func__, remaining);
1793 return retval;
1794 }
1795
1796 retval = synaptics_rmi4_reg_write(rmi4_data,
1797 base + fwu->off.payload,
1798 block_ptr,
1799 transfer * fwu->block_size);
1800 if (retval < 0) {
1801 dev_err(rmi4_data->pdev->dev.parent,
1802 "%s: Failed to write block data (%d blocks remaining)\n",
1803 __func__, remaining);
1804 return retval;
1805 }
1806
1807 retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
1808 if (retval < 0) {
1809 dev_err(rmi4_data->pdev->dev.parent,
1810 "%s: Failed to wait for idle status (%d blocks remaining)\n",
1811 __func__, remaining);
1812 return retval;
1813 }
1814
1815 block_ptr += (transfer * fwu->block_size);
1816 remaining -= transfer;
1817 } while (remaining);
1818
1819 return 0;
1820}
1821
1822static int fwu_write_f34_v5v6_blocks(unsigned char *block_ptr,
1823 unsigned short block_cnt, unsigned char command)
1824{
1825 int retval;
1826 unsigned char base;
1827 unsigned char block_number[] = {0, 0};
1828 unsigned short blk;
1829 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1830
1831 base = fwu->f34_fd.data_base_addr;
1832
1833 block_number[1] |= (fwu->config_area << 5);
1834
1835 retval = synaptics_rmi4_reg_write(rmi4_data,
1836 base + fwu->off.block_number,
1837 block_number,
1838 sizeof(block_number));
1839 if (retval < 0) {
1840 dev_err(rmi4_data->pdev->dev.parent,
1841 "%s: Failed to write block number\n",
1842 __func__);
1843 return retval;
1844 }
1845
1846 for (blk = 0; blk < block_cnt; blk++) {
1847 retval = synaptics_rmi4_reg_write(rmi4_data,
1848 base + fwu->off.payload,
1849 block_ptr,
1850 fwu->block_size);
1851 if (retval < 0) {
1852 dev_err(rmi4_data->pdev->dev.parent,
1853 "%s: Failed to write block data (block %d)\n",
1854 __func__, blk);
1855 return retval;
1856 }
1857
1858 retval = fwu_write_f34_command(command);
1859 if (retval < 0) {
1860 dev_err(rmi4_data->pdev->dev.parent,
1861 "%s: Failed to write command for block %d\n",
1862 __func__, blk);
1863 return retval;
1864 }
1865
1866 retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
1867 if (retval < 0) {
1868 dev_err(rmi4_data->pdev->dev.parent,
1869 "%s: Failed to wait for idle status (block %d)\n",
1870 __func__, blk);
1871 return retval;
1872 }
1873
1874 block_ptr += fwu->block_size;
1875 }
1876
1877 return 0;
1878}
1879
1880static int fwu_write_f34_blocks(unsigned char *block_ptr,
1881 unsigned short block_cnt, unsigned char cmd)
1882{
1883 int retval;
1884
1885 if (fwu->bl_version == BL_V7)
1886 retval = fwu_write_f34_v7_blocks(block_ptr, block_cnt, cmd);
1887 else
1888 retval = fwu_write_f34_v5v6_blocks(block_ptr, block_cnt, cmd);
1889
1890 return retval;
1891}
1892
1893static int fwu_read_f34_v7_blocks(unsigned short block_cnt,
1894 unsigned char command)
1895{
1896 int retval;
1897 unsigned char base;
1898 unsigned char length[2];
1899 unsigned short transfer;
1900 unsigned short max_transfer;
1901 unsigned short remaining = block_cnt;
1902 unsigned short block_number = 0;
1903 unsigned short index = 0;
1904 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1905
1906 base = fwu->f34_fd.data_base_addr;
1907
1908 retval = fwu_write_f34_partition_id(command);
1909 if (retval < 0)
1910 return retval;
1911
1912 retval = synaptics_rmi4_reg_write(rmi4_data,
1913 base + fwu->off.block_number,
1914 (unsigned char *)&block_number,
1915 sizeof(block_number));
1916 if (retval < 0) {
1917 dev_err(rmi4_data->pdev->dev.parent,
1918 "%s: Failed to write block number\n",
1919 __func__);
1920 return retval;
1921 }
1922
1923 if (fwu->payload_length > (PAGE_SIZE / fwu->block_size))
1924 max_transfer = PAGE_SIZE / fwu->block_size;
1925 else
1926 max_transfer = fwu->payload_length;
1927
1928 do {
1929 if (remaining / max_transfer)
1930 transfer = max_transfer;
1931 else
1932 transfer = remaining;
1933
1934 length[0] = (unsigned char)(transfer & MASK_8BIT);
1935 length[1] = (unsigned char)(transfer >> 8);
1936
1937 retval = synaptics_rmi4_reg_write(rmi4_data,
1938 base + fwu->off.transfer_length,
1939 length,
1940 sizeof(length));
1941 if (retval < 0) {
1942 dev_err(rmi4_data->pdev->dev.parent,
1943 "%s: Failed to write transfer length (%d blocks remaining)\n",
1944 __func__, remaining);
1945 return retval;
1946 }
1947
1948 retval = fwu_write_f34_command(command);
1949 if (retval < 0) {
1950 dev_err(rmi4_data->pdev->dev.parent,
1951 "%s: Failed to write command (%d blocks remaining)\n",
1952 __func__, remaining);
1953 return retval;
1954 }
1955
1956 retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
1957 if (retval < 0) {
1958 dev_err(rmi4_data->pdev->dev.parent,
1959 "%s: Failed to wait for idle status (%d blocks remaining)\n",
1960 __func__, remaining);
1961 return retval;
1962 }
1963
1964 retval = synaptics_rmi4_reg_read(rmi4_data,
1965 base + fwu->off.payload,
1966 &fwu->read_config_buf[index],
1967 transfer * fwu->block_size);
1968 if (retval < 0) {
1969 dev_err(rmi4_data->pdev->dev.parent,
1970 "%s: Failed to read block data (%d blocks remaining)\n",
1971 __func__, remaining);
1972 return retval;
1973 }
1974
1975 index += (transfer * fwu->block_size);
1976 remaining -= transfer;
1977 } while (remaining);
1978
1979 return 0;
1980}
1981
1982static int fwu_read_f34_v5v6_blocks(unsigned short block_cnt,
1983 unsigned char command)
1984{
1985 int retval;
1986 unsigned char base;
1987 unsigned char block_number[] = {0, 0};
1988 unsigned short blk;
1989 unsigned short index = 0;
1990 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1991
1992 base = fwu->f34_fd.data_base_addr;
1993
1994 block_number[1] |= (fwu->config_area << 5);
1995
1996 retval = synaptics_rmi4_reg_write(rmi4_data,
1997 base + fwu->off.block_number,
1998 block_number,
1999 sizeof(block_number));
2000 if (retval < 0) {
2001 dev_err(rmi4_data->pdev->dev.parent,
2002 "%s: Failed to write block number\n",
2003 __func__);
2004 return retval;
2005 }
2006
2007 for (blk = 0; blk < block_cnt; blk++) {
2008 retval = fwu_write_f34_command(command);
2009 if (retval < 0) {
2010 dev_err(rmi4_data->pdev->dev.parent,
2011 "%s: Failed to write read config command\n",
2012 __func__);
2013 return retval;
2014 }
2015
2016 retval = fwu_wait_for_idle(WRITE_WAIT_MS, false);
2017 if (retval < 0) {
2018 dev_err(rmi4_data->pdev->dev.parent,
2019 "%s: Failed to wait for idle status\n",
2020 __func__);
2021 return retval;
2022 }
2023
2024 retval = synaptics_rmi4_reg_read(rmi4_data,
2025 base + fwu->off.payload,
2026 &fwu->read_config_buf[index],
2027 fwu->block_size);
2028 if (retval < 0) {
2029 dev_err(rmi4_data->pdev->dev.parent,
2030 "%s: Failed to read block data (block %d)\n",
2031 __func__, blk);
2032 return retval;
2033 }
2034
2035 index += fwu->block_size;
2036 }
2037
2038 return 0;
2039}
2040
2041static int fwu_read_f34_blocks(unsigned short block_cnt, unsigned char cmd)
2042{
2043 int retval;
2044
2045 if (fwu->bl_version == BL_V7)
2046 retval = fwu_read_f34_v7_blocks(block_cnt, cmd);
2047 else
2048 retval = fwu_read_f34_v5v6_blocks(block_cnt, cmd);
2049
2050 return retval;
2051}
2052
2053static int fwu_get_image_firmware_id(unsigned int *fw_id)
2054{
2055 int retval;
2056 unsigned char index = 0;
2057 char *strptr;
2058 char *firmware_id;
2059 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2060
2061 if (fwu->img.contains_firmware_id) {
2062 *fw_id = fwu->img.firmware_id;
2063 } else {
2064 strptr = strstr(fwu->image_name, "PR");
2065 if (!strptr) {
2066 dev_err(rmi4_data->pdev->dev.parent,
2067 "%s: No valid PR number (PRxxxxxxx) "
2068 "found in image file name (%s)\n",
2069 __func__, fwu->image_name);
2070 return -EINVAL;
2071 }
2072
2073 strptr += 2;
2074 firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL);
2075 if (!firmware_id) {
2076 dev_err(rmi4_data->pdev->dev.parent,
2077 "%s: Failed to alloc mem for firmware_id\n",
2078 __func__);
2079 return -ENOMEM;
2080 }
2081 while (strptr[index] >= '0' && strptr[index] <= '9') {
2082 firmware_id[index] = strptr[index];
2083 index++;
2084 }
2085
2086 retval = sstrtoul(firmware_id, 10, (unsigned long *)fw_id);
2087 kfree(firmware_id);
2088 if (retval) {
2089 dev_err(rmi4_data->pdev->dev.parent,
2090 "%s: Failed to obtain image firmware ID\n",
2091 __func__);
2092 return -EINVAL;
2093 }
2094 }
2095
2096 return 0;
2097}
2098
2099static enum flash_area fwu_go_nogo(void)
2100{
2101 int retval;
2102 enum flash_area flash_area = NONE;
2103 unsigned char config_id[4];
2104 unsigned int device_config_id;
2105 unsigned int image_config_id;
2106 unsigned int device_fw_id;
2107 unsigned int image_fw_id;
2108 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2109
2110 if (fwu->force_update) {
2111 flash_area = UI_FIRMWARE;
2112 goto exit;
2113 }
2114
2115 /* Update both UI and config if device is in bootloader mode */
2116 if (fwu->in_bl_mode) {
2117 flash_area = UI_FIRMWARE;
2118 goto exit;
2119 }
2120
2121 /* Get device firmware ID */
2122 device_fw_id = rmi4_data->firmware_id;
2123 dev_info(rmi4_data->pdev->dev.parent,
2124 "%s: Device firmware ID = %d\n",
2125 __func__, device_fw_id);
2126
2127 /* Get image firmware ID */
2128 retval = fwu_get_image_firmware_id(&image_fw_id);
2129 if (retval < 0) {
2130 flash_area = NONE;
2131 goto exit;
2132 }
2133 dev_info(rmi4_data->pdev->dev.parent,
2134 "%s: Image firmware ID = %d\n",
2135 __func__, image_fw_id);
2136
2137 if (image_fw_id > device_fw_id) {
2138 flash_area = UI_FIRMWARE;
2139 goto exit;
2140 } else if (image_fw_id < device_fw_id) {
2141 dev_info(rmi4_data->pdev->dev.parent,
2142 "%s: Image firmware ID older than device firmware ID\n",
2143 __func__);
2144 flash_area = NONE;
2145 goto exit;
2146 }
2147
2148 /* Get device config ID */
2149 retval = synaptics_rmi4_reg_read(rmi4_data,
2150 fwu->f34_fd.ctrl_base_addr,
2151 config_id,
2152 sizeof(config_id));
2153 if (retval < 0) {
2154 dev_err(rmi4_data->pdev->dev.parent,
2155 "%s: Failed to read device config ID\n",
2156 __func__);
2157 flash_area = NONE;
2158 goto exit;
2159 }
2160 device_config_id = be_to_uint(config_id);
2161 dev_info(rmi4_data->pdev->dev.parent,
2162 "%s: Device config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n",
2163 __func__,
2164 config_id[0],
2165 config_id[1],
2166 config_id[2],
2167 config_id[3]);
2168
2169 /* Get image config ID */
2170 image_config_id = be_to_uint(fwu->img.ui_config.data);
2171 dev_info(rmi4_data->pdev->dev.parent,
2172 "%s: Image config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n",
2173 __func__,
2174 fwu->img.ui_config.data[0],
2175 fwu->img.ui_config.data[1],
2176 fwu->img.ui_config.data[2],
2177 fwu->img.ui_config.data[3]);
2178
2179 if (image_config_id > device_config_id) {
2180 flash_area = UI_CONFIG;
2181 goto exit;
2182 }
2183
2184 flash_area = NONE;
liuyan04291e030782016-03-04 11:23:23 +08002185
liuyan451acd62015-01-27 10:03:09 +08002186exit:
2187 if (flash_area == NONE) {
2188 dev_info(rmi4_data->pdev->dev.parent,
2189 "%s: No need to do reflash\n",
2190 __func__);
2191 } else {
2192 dev_info(rmi4_data->pdev->dev.parent,
2193 "%s: Updating %s\n",
2194 __func__,
2195 flash_area == UI_FIRMWARE ?
2196 "UI firmware and config" :
2197 "UI config only");
2198 }
2199
2200 return flash_area;
2201}
2202
2203static int fwu_scan_pdt(void)
2204{
2205 int retval;
2206 unsigned char ii;
2207 unsigned char intr_count = 0;
2208 unsigned char intr_off;
2209 unsigned char intr_src;
2210 unsigned short addr;
2211 bool f01found = false;
2212 bool f34found = false;
2213 struct synaptics_rmi4_fn_desc rmi_fd;
2214 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2215
2216 for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
2217 retval = synaptics_rmi4_reg_read(rmi4_data,
2218 addr,
2219 (unsigned char *)&rmi_fd,
2220 sizeof(rmi_fd));
2221 if (retval < 0)
2222 return retval;
2223
2224 if (rmi_fd.fn_number) {
2225 dev_dbg(rmi4_data->pdev->dev.parent,
2226 "%s: Found F%02x\n",
2227 __func__, rmi_fd.fn_number);
2228 switch (rmi_fd.fn_number) {
2229 case SYNAPTICS_RMI4_F01:
2230 f01found = true;
2231
2232 rmi4_data->f01_query_base_addr =
2233 rmi_fd.query_base_addr;
2234 rmi4_data->f01_ctrl_base_addr =
2235 rmi_fd.ctrl_base_addr;
2236 rmi4_data->f01_data_base_addr =
2237 rmi_fd.data_base_addr;
2238 rmi4_data->f01_cmd_base_addr =
2239 rmi_fd.cmd_base_addr;
2240 break;
2241 case SYNAPTICS_RMI4_F34:
2242 f34found = true;
2243 fwu->f34_fd.query_base_addr =
2244 rmi_fd.query_base_addr;
2245 fwu->f34_fd.ctrl_base_addr =
2246 rmi_fd.ctrl_base_addr;
2247 fwu->f34_fd.data_base_addr =
2248 rmi_fd.data_base_addr;
2249
2250 switch (rmi_fd.fn_version) {
2251 case F34_V0:
2252 fwu->bl_version = BL_V5;
2253 break;
2254 case F34_V1:
2255 fwu->bl_version = BL_V6;
2256 break;
2257 case F34_V2:
2258 fwu->bl_version = BL_V7;
2259 break;
2260 default:
2261 dev_err(rmi4_data->pdev->dev.parent,
2262 "%s: Unrecognized F34 version\n",
2263 __func__);
2264 return -EINVAL;
2265 }
2266
2267 fwu->intr_mask = 0;
2268 intr_src = rmi_fd.intr_src_count;
2269 intr_off = intr_count % 8;
2270 for (ii = intr_off;
2271 ii < (intr_src + intr_off);
2272 ii++) {
2273 fwu->intr_mask |= 1 << ii;
2274 }
2275 break;
2276 }
2277 } else {
2278 break;
2279 }
2280
2281 intr_count += rmi_fd.intr_src_count;
2282 }
2283
2284 if (!f01found || !f34found) {
2285 dev_err(rmi4_data->pdev->dev.parent,
2286 "%s: Failed to find both F01 and F34\n",
2287 __func__);
2288 return -EINVAL;
2289 }
2290
2291 rmi4_data->intr_mask[0] |= fwu->intr_mask;
2292
2293 addr = rmi4_data->f01_ctrl_base_addr + 1;
2294
2295 retval = synaptics_rmi4_reg_write(rmi4_data,
2296 addr,
2297 &(rmi4_data->intr_mask[0]),
2298 sizeof(rmi4_data->intr_mask[0]));
2299 if (retval < 0) {
2300 dev_err(rmi4_data->pdev->dev.parent,
2301 "%s: Failed to set interrupt enable bit\n",
2302 __func__);
2303 return retval;
2304 }
2305
2306 return 0;
2307}
2308
2309static int fwu_enter_flash_prog(void)
2310{
2311 int retval;
2312 struct f01_device_control f01_device_control;
2313 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2314
2315 retval = fwu_read_flash_status();
2316 if (retval < 0)
2317 return retval;
2318
2319 if (fwu->in_bl_mode)
2320 return 0;
2321
2322 retval = rmi4_data->irq_enable(rmi4_data, false, true);
2323 if (retval < 0)
2324 return retval;
2325
2326 msleep(INT_DISABLE_WAIT_MS);
2327
2328 retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
2329 if (retval < 0)
2330 return retval;
2331
2332 retval = fwu_wait_for_idle(ENABLE_WAIT_MS, false);
2333 if (retval < 0)
2334 return retval;
2335
2336 if (!fwu->in_bl_mode) {
2337 dev_err(rmi4_data->pdev->dev.parent,
2338 "%s: BL mode not entered\n",
2339 __func__);
2340 return -EINVAL;
2341 }
2342
2343 if (rmi4_data->hw_if->bl_hw_init) {
2344 retval = rmi4_data->hw_if->bl_hw_init(rmi4_data);
2345 if (retval < 0)
2346 return retval;
2347 }
2348
2349 retval = fwu_scan_pdt();
2350 if (retval < 0)
2351 return retval;
2352
2353 retval = synaptics_rmi4_reg_read(rmi4_data,
2354 rmi4_data->f01_ctrl_base_addr,
2355 f01_device_control.data,
2356 sizeof(f01_device_control.data));
2357 if (retval < 0) {
2358 dev_err(rmi4_data->pdev->dev.parent,
2359 "%s: Failed to read F01 device control\n",
2360 __func__);
2361 return retval;
2362 }
2363
2364 f01_device_control.nosleep = true;
2365 f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
2366
2367 retval = synaptics_rmi4_reg_write(rmi4_data,
2368 rmi4_data->f01_ctrl_base_addr,
2369 f01_device_control.data,
2370 sizeof(f01_device_control.data));
2371 if (retval < 0) {
2372 dev_err(rmi4_data->pdev->dev.parent,
2373 "%s: Failed to write F01 device control\n",
2374 __func__);
2375 return retval;
2376 }
2377
2378 msleep(ENTER_FLASH_PROG_WAIT_MS);
2379
2380 return retval;
2381}
2382
2383static int fwu_check_ui_firmware_size(void)
2384{
2385 unsigned short block_count;
2386 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2387
2388 block_count = fwu->img.ui_firmware.size / fwu->block_size;
2389
2390 if (block_count != fwu->blkcount.ui_firmware) {
2391 dev_err(rmi4_data->pdev->dev.parent,
2392 "%s: UI firmware size mismatch\n",
2393 __func__);
2394 return -EINVAL;
2395 }
2396
2397 return 0;
2398}
2399
2400static int fwu_check_ui_configuration_size(void)
2401{
2402 unsigned short block_count;
2403 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2404
2405 block_count = fwu->img.ui_config.size / fwu->block_size;
2406
2407 if (block_count != fwu->blkcount.ui_config) {
2408 dev_err(rmi4_data->pdev->dev.parent,
2409 "%s: UI configuration size mismatch\n",
2410 __func__);
2411 return -EINVAL;
2412 }
2413
2414 return 0;
2415}
2416
2417static int fwu_check_dp_configuration_size(void)
2418{
2419 unsigned short block_count;
2420 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2421
2422 block_count = fwu->img.dp_config.size / fwu->block_size;
2423
2424 if (block_count != fwu->blkcount.dp_config) {
2425 dev_err(rmi4_data->pdev->dev.parent,
2426 "%s: Display configuration size mismatch\n",
2427 __func__);
2428 return -EINVAL;
2429 }
2430
2431 return 0;
2432}
2433
2434static int fwu_check_bl_configuration_size(void)
2435{
2436 unsigned short block_count;
2437 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2438
2439 block_count = fwu->img.bl_config.size / fwu->block_size;
2440
2441 if (block_count != fwu->blkcount.bl_config) {
2442 dev_err(rmi4_data->pdev->dev.parent,
2443 "%s: Bootloader configuration size mismatch\n",
2444 __func__);
2445 return -EINVAL;
2446 }
2447
2448 return 0;
2449}
2450
2451static int fwu_check_guest_code_size(void)
2452{
2453 unsigned short block_count;
2454 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2455
2456 block_count = fwu->img.guest_code.size / fwu->block_size;
2457 if (block_count != fwu->blkcount.guest_code) {
2458 dev_err(rmi4_data->pdev->dev.parent,
2459 "%s: Guest code size mismatch\n",
2460 __func__);
2461 return -EINVAL;
2462 }
2463
2464 return 0;
2465}
2466
2467static int fwu_write_firmware(void)
2468{
2469 unsigned short firmware_block_count;
2470
2471 firmware_block_count = fwu->img.ui_firmware.size / fwu->block_size;
2472
2473 return fwu_write_f34_blocks((unsigned char *)fwu->img.ui_firmware.data,
2474 firmware_block_count, CMD_WRITE_FW);
2475}
2476
2477static int fwu_erase_configuration(void)
2478{
2479 int retval;
2480 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2481
2482 switch (fwu->config_area) {
2483 case UI_CONFIG_AREA:
2484 retval = fwu_write_f34_command(CMD_ERASE_UI_CONFIG);
2485 if (retval < 0)
2486 return retval;
2487 break;
2488 case DP_CONFIG_AREA:
2489 retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
2490 if (retval < 0)
2491 return retval;
2492 break;
2493 case BL_CONFIG_AREA:
2494 retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
2495 if (retval < 0)
2496 return retval;
2497 break;
2498 }
2499
2500 dev_dbg(rmi4_data->pdev->dev.parent,
2501 "%s: Erase command written\n",
2502 __func__);
2503
2504 retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
2505 if (retval < 0)
2506 return retval;
2507
2508 dev_dbg(rmi4_data->pdev->dev.parent,
2509 "%s: Idle status detected\n",
2510 __func__);
2511
2512 return retval;
2513}
2514
2515static int fwu_erase_guest_code(void)
2516{
2517 int retval;
2518 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2519
2520 retval = fwu_write_f34_command(CMD_ERASE_GUEST_CODE);
2521 if (retval < 0)
2522 return retval;
2523
2524 dev_dbg(rmi4_data->pdev->dev.parent,
2525 "%s: Erase command written\n",
2526 __func__);
2527
2528 retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
2529 if (retval < 0)
2530 return retval;
2531
2532 dev_dbg(rmi4_data->pdev->dev.parent,
2533 "%s: Idle status detected\n",
2534 __func__);
2535
2536 return 0;
2537}
2538
2539static int fwu_erase_all(void)
2540{
2541 int retval;
2542 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2543
2544 if (fwu->bl_version == BL_V7) {
2545 retval = fwu_write_f34_command(CMD_ERASE_UI_FIRMWARE);
2546 if (retval < 0)
2547 return retval;
2548
2549 dev_dbg(rmi4_data->pdev->dev.parent,
2550 "%s: Erase command written\n",
2551 __func__);
2552
2553 retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
2554 if (retval < 0)
2555 return retval;
2556
2557 dev_dbg(rmi4_data->pdev->dev.parent,
2558 "%s: Idle status detected\n",
2559 __func__);
2560
2561 fwu->config_area = UI_CONFIG_AREA;
2562 retval = fwu_erase_configuration();
2563 if (retval < 0)
2564 return retval;
2565 } else {
2566 retval = fwu_write_f34_command(CMD_ERASE_ALL);
2567 if (retval < 0)
2568 return retval;
2569
2570 dev_dbg(rmi4_data->pdev->dev.parent,
2571 "%s: Erase all command written\n",
2572 __func__);
2573
2574 retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
2575 if (retval < 0)
2576 return retval;
2577
2578 dev_dbg(rmi4_data->pdev->dev.parent,
2579 "%s: Idle status detected\n",
2580 __func__);
2581 }
2582
2583 if (fwu->flash_properties.has_disp_config) {
2584 fwu->config_area = DP_CONFIG_AREA;
2585 retval = fwu_erase_configuration();
2586 if (retval < 0)
2587 return retval;
2588 }
2589
2590 if (fwu->new_partition_table && fwu->has_guest_code) {
2591 retval = fwu_erase_guest_code();
2592 if (retval < 0)
2593 return retval;
2594 }
2595
2596 return 0;
2597}
2598
2599static int fwu_write_configuration(void)
2600{
2601 return fwu_write_f34_blocks((unsigned char *)fwu->config_data,
2602 fwu->config_block_count, CMD_WRITE_CONFIG);
2603}
2604
2605static int fwu_write_ui_configuration(void)
2606{
2607 fwu->config_area = UI_CONFIG_AREA;
2608 fwu->config_data = fwu->img.ui_config.data;
2609 fwu->config_size = fwu->img.ui_config.size;
2610 fwu->config_block_count = fwu->config_size / fwu->block_size;
2611
2612 return fwu_write_configuration();
2613}
2614
2615static int fwu_write_dp_configuration(void)
2616{
2617 fwu->config_area = DP_CONFIG_AREA;
2618 fwu->config_data = fwu->img.dp_config.data;
2619 fwu->config_size = fwu->img.dp_config.size;
2620 fwu->config_block_count = fwu->config_size / fwu->block_size;
2621
2622 return fwu_write_configuration();
2623}
2624
2625static int fwu_write_flash_configuration(void)
2626{
2627 int retval;
2628 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2629
2630 fwu->config_area = FLASH_CONFIG_AREA;
2631 fwu->config_data = fwu->img.fl_config.data;
2632 fwu->config_size = fwu->img.fl_config.size;
2633 fwu->config_block_count = fwu->config_size / fwu->block_size;
2634
2635 if (fwu->config_block_count != fwu->blkcount.fl_config) {
2636 dev_err(rmi4_data->pdev->dev.parent,
2637 "%s: Flash configuration size mismatch\n",
2638 __func__);
2639 return -EINVAL;
2640 }
2641
2642 retval = fwu_write_f34_command(CMD_ERASE_FLASH_CONFIG);
2643 if (retval < 0)
2644 return retval;
2645
2646 dev_dbg(rmi4_data->pdev->dev.parent,
2647 "%s: Erase flash configuration command written\n",
2648 __func__);
2649
2650 retval = fwu_wait_for_idle(ERASE_WAIT_MS, false);
2651 if (retval < 0)
2652 return retval;
2653
2654 dev_dbg(rmi4_data->pdev->dev.parent,
2655 "%s: Idle status detected\n",
2656 __func__);
2657
2658 retval = fwu_write_configuration();
2659 if (retval < 0)
2660 return retval;
2661
2662 rmi4_data->reset_device(rmi4_data);
2663
2664 return 0;
2665}
2666
2667static int fwu_write_guest_code(void)
2668{
2669 int retval;
2670 unsigned short guest_code_block_count;
2671
2672 guest_code_block_count = fwu->img.guest_code.size / fwu->block_size;
2673
2674 retval = fwu_write_f34_blocks((unsigned char *)fwu->img.guest_code.data,
2675 guest_code_block_count, CMD_WRITE_GUEST_CODE);
2676 if (retval < 0)
2677 return retval;
2678
2679 return 0;
2680}
2681
2682static int fwu_write_lockdown(void)
2683{
2684 unsigned short lockdown_block_count;
2685
2686 lockdown_block_count = fwu->img.lockdown.size / fwu->block_size;
2687
2688 return fwu_write_f34_blocks((unsigned char *)fwu->img.lockdown.data,
2689 lockdown_block_count, CMD_WRITE_LOCKDOWN);
2690}
2691
2692static int fwu_write_partition_table(void)
2693{
2694 int retval;
2695 unsigned short block_count;
2696 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2697
2698 block_count = fwu->blkcount.bl_config;
2699 fwu->config_area = BL_CONFIG_AREA;
2700 fwu->config_size = fwu->block_size * block_count;
2701 kfree(fwu->read_config_buf);
2702 fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
2703 if (!fwu->read_config_buf) {
2704 dev_err(rmi4_data->pdev->dev.parent,
2705 "%s: Failed to alloc mem for fwu->read_config_buf\n",
2706 __func__);
2707 fwu->read_config_buf_size = 0;
2708 return -ENOMEM;
2709 }
2710 fwu->read_config_buf_size = fwu->config_size;
2711
2712 retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG);
2713 if (retval < 0)
2714 return retval;
2715
2716 retval = fwu_erase_configuration();
2717 if (retval < 0)
2718 return retval;
2719
2720 retval = fwu_write_flash_configuration();
2721 if (retval < 0)
2722 return retval;
2723
2724 fwu->config_area = BL_CONFIG_AREA;
2725 fwu->config_data = fwu->read_config_buf;
2726 fwu->config_size = fwu->img.bl_config.size;
2727 fwu->config_block_count = fwu->config_size / fwu->block_size;
2728
2729 retval = fwu_write_configuration();
2730 if (retval < 0)
2731 return retval;
2732
2733 return 0;
2734}
2735
2736static int fwu_do_reflash(void)
2737{
2738 int retval;
2739
2740 if (!fwu->new_partition_table) {
2741 retval = fwu_check_ui_firmware_size();
2742 if (retval < 0)
2743 return retval;
2744
2745 retval = fwu_check_ui_configuration_size();
2746 if (retval < 0)
2747 return retval;
2748
2749 if (fwu->flash_properties.has_disp_config &&
2750 fwu->img.contains_disp_config) {
2751 retval = fwu_check_dp_configuration_size();
2752 if (retval < 0)
2753 return retval;
2754 }
2755
2756 if (fwu->has_guest_code && fwu->img.contains_guest_code) {
2757 retval = fwu_check_guest_code_size();
2758 if (retval < 0)
2759 return retval;
2760 }
2761 } else {
2762 retval = fwu_check_bl_configuration_size();
2763 if (retval < 0)
2764 return retval;
2765 }
2766
2767 retval = fwu_erase_all();
2768 if (retval < 0)
2769 return retval;
2770
2771 if (fwu->new_partition_table) {
2772 retval = fwu_write_partition_table();
2773 if (retval < 0)
2774 return retval;
2775 pr_notice("%s: Partition table programmed\n", __func__);
2776 }
2777
2778 retval = fwu_write_firmware();
2779 if (retval < 0)
2780 return retval;
2781 pr_notice("%s: Firmware programmed\n", __func__);
2782
2783 fwu->config_area = UI_CONFIG_AREA;
2784 retval = fwu_write_ui_configuration();
2785 if (retval < 0)
2786 return retval;
2787 pr_notice("%s: Configuration programmed\n", __func__);
2788
2789 if (fwu->flash_properties.has_disp_config &&
2790 fwu->img.contains_disp_config) {
2791 retval = fwu_write_dp_configuration();
2792 if (retval < 0)
2793 return retval;
2794 pr_notice("%s: Display configuration programmed\n", __func__);
2795 }
2796
2797 if (fwu->new_partition_table) {
2798 if (fwu->has_guest_code && fwu->img.contains_guest_code) {
2799 retval = fwu_write_guest_code();
2800 if (retval < 0)
2801 return retval;
2802 pr_notice("%s: Guest code programmed\n", __func__);
2803 }
2804 }
2805
2806 return retval;
2807}
2808
2809static int fwu_do_read_config(void)
2810{
2811 int retval;
2812 unsigned short block_count;
2813 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2814
2815 switch (fwu->config_area) {
2816 case UI_CONFIG_AREA:
2817 block_count = fwu->blkcount.ui_config;
2818 break;
2819 case DP_CONFIG_AREA:
2820 if (!fwu->flash_properties.has_disp_config) {
2821 dev_err(rmi4_data->pdev->dev.parent,
2822 "%s: Display configuration not supported\n",
2823 __func__);
2824 return -EINVAL;
2825 }
2826 block_count = fwu->blkcount.dp_config;
2827 break;
2828 case PM_CONFIG_AREA:
2829 if (!fwu->flash_properties.has_pm_config) {
2830 dev_err(rmi4_data->pdev->dev.parent,
2831 "%s: Permanent configuration not supported\n",
2832 __func__);
2833 return -EINVAL;
2834 }
2835 block_count = fwu->blkcount.pm_config;
2836 break;
2837 case BL_CONFIG_AREA:
2838 if (!fwu->flash_properties.has_bl_config) {
2839 dev_err(rmi4_data->pdev->dev.parent,
2840 "%s: Bootloader configuration not supported\n",
2841 __func__);
2842 return -EINVAL;
2843 }
2844 block_count = fwu->blkcount.bl_config;
2845 break;
2846 default:
2847 dev_err(rmi4_data->pdev->dev.parent,
2848 "%s: Invalid config area\n",
2849 __func__);
2850 return -EINVAL;
2851 }
2852
2853 if (block_count == 0) {
2854 dev_err(rmi4_data->pdev->dev.parent,
2855 "%s: Invalid block count\n",
2856 __func__);
2857 return -EINVAL;
2858 }
2859
2860 retval = fwu_enter_flash_prog();
2861 if (retval < 0)
2862 goto exit;
2863
2864 fwu->config_size = fwu->block_size * block_count;
2865 kfree(fwu->read_config_buf);
2866 fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
2867 if (!fwu->read_config_buf) {
2868 dev_err(rmi4_data->pdev->dev.parent,
2869 "%s: Failed to alloc mem for fwu->read_config_buf\n",
2870 __func__);
2871 fwu->read_config_buf_size = 0;
2872 retval = -ENOMEM;
2873 goto exit;
2874 }
2875 fwu->read_config_buf_size = fwu->config_size;
2876
2877 retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG);
2878
2879exit:
2880 rmi4_data->reset_device(rmi4_data);
2881
2882 return retval;
2883}
2884
2885static int fwu_do_lockdown(void)
2886{
2887 int retval;
2888 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2889
2890 retval = fwu_enter_flash_prog();
2891 if (retval < 0)
2892 return retval;
2893
2894 retval = synaptics_rmi4_reg_read(rmi4_data,
2895 fwu->f34_fd.query_base_addr + fwu->off.properties,
2896 fwu->flash_properties.data,
2897 sizeof(fwu->flash_properties.data));
2898 if (retval < 0) {
2899 dev_err(rmi4_data->pdev->dev.parent,
2900 "%s: Failed to read flash properties\n",
2901 __func__);
2902 return retval;
2903 }
2904
2905 if (fwu->flash_properties.unlocked == 0) {
2906 dev_info(rmi4_data->pdev->dev.parent,
2907 "%s: Device already locked down\n",
2908 __func__);
2909 return 0;
2910 }
2911
2912 retval = fwu_write_lockdown();
2913 if (retval < 0)
2914 return retval;
2915
2916 pr_notice("%s: Lockdown programmed\n", __func__);
2917
2918 return retval;
2919}
2920
2921static int fwu_start_write_guest_code(void)
2922{
2923 int retval;
2924 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2925
2926 retval = fwu_parse_image_info();
2927 if (retval < 0)
2928 return -EINVAL;
2929
2930 if (!fwu->has_guest_code) {
2931 dev_err(rmi4_data->pdev->dev.parent,
2932 "%s: Guest code not supported\n",
2933 __func__);
2934 return -EINVAL;
2935 }
2936
2937 if (!fwu->img.contains_guest_code) {
2938 dev_err(rmi4_data->pdev->dev.parent,
2939 "%s: No guest code in firmware image\n",
2940 __func__);
2941 return -EINVAL;
2942 }
2943
2944 pr_notice("%s: Start of write guest code process\n", __func__);
2945
2946 retval = fwu_enter_flash_prog();
2947 if (retval < 0)
2948 goto exit;
2949
2950 retval = fwu_check_guest_code_size();
2951 if (retval < 0)
2952 goto exit;
2953
2954 retval = fwu_erase_guest_code();
2955 if (retval < 0)
2956 goto exit;
2957
2958 retval = fwu_write_guest_code();
2959 if (retval < 0)
2960 goto exit;
2961
2962 pr_notice("%s: Guest code programmed\n", __func__);
2963
2964exit:
2965 rmi4_data->reset_device(rmi4_data);
2966
2967 pr_notice("%s: End of write guest code process\n", __func__);
2968
2969 return retval;
2970}
2971
2972static int fwu_start_write_config(void)
2973{
2974 int retval;
2975 unsigned int device_fw_id;
2976 unsigned int image_fw_id;
2977 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
2978
2979 retval = fwu_parse_image_info();
2980 if (retval < 0)
2981 return -EINVAL;
2982
2983 switch (fwu->config_area) {
2984 case UI_CONFIG_AREA:
2985 device_fw_id = rmi4_data->firmware_id;
2986 retval = fwu_get_image_firmware_id(&image_fw_id);
2987 if (retval < 0)
2988 return retval;
2989 if (device_fw_id != image_fw_id) {
2990 dev_err(rmi4_data->pdev->dev.parent,
2991 "%s: Device and image firmware IDs don't match\n",
2992 __func__);
2993 return -EINVAL;
2994 }
2995 retval = fwu_check_ui_configuration_size();
2996 if (retval < 0)
2997 return retval;
2998 break;
2999 case DP_CONFIG_AREA:
3000 if (!fwu->flash_properties.has_disp_config) {
3001 dev_err(rmi4_data->pdev->dev.parent,
3002 "%s: Display configuration not supported\n",
3003 __func__);
3004 return -EINVAL;
3005 }
3006 if (!fwu->img.contains_disp_config) {
3007 dev_err(rmi4_data->pdev->dev.parent,
3008 "%s: No display configuration in firmware image\n",
3009 __func__);
3010 return -EINVAL;
3011 }
3012 retval = fwu_check_dp_configuration_size();
3013 if (retval < 0)
3014 return retval;
3015 break;
3016 default:
3017 dev_err(rmi4_data->pdev->dev.parent,
3018 "%s: Configuration not supported\n",
3019 __func__);
3020 return -EINVAL;
3021 }
3022
3023 pr_notice("%s: Start of write config process\n", __func__);
3024
3025 retval = fwu_enter_flash_prog();
3026 if (retval < 0)
3027 goto exit;
3028
3029 retval = fwu_erase_configuration();
3030 if (retval < 0) {
3031 dev_err(rmi4_data->pdev->dev.parent,
3032 "%s: Failed to erase config\n",
3033 __func__);
3034 goto exit;
3035 }
3036
3037 switch (fwu->config_area) {
3038 case UI_CONFIG_AREA:
3039 retval = fwu_write_ui_configuration();
3040 if (retval < 0)
3041 goto exit;
3042 break;
3043 case DP_CONFIG_AREA:
3044 retval = fwu_write_dp_configuration();
3045 if (retval < 0)
3046 goto exit;
3047 break;
3048 }
3049
3050 pr_notice("%s: Config written\n", __func__);
3051
3052exit:
3053 rmi4_data->reset_device(rmi4_data);
3054
3055 pr_notice("%s: End of write config process\n", __func__);
3056
3057 return retval;
3058}
3059
3060static int fwu_start_reflash(void)
3061{
3062 int retval = 0;
3063 enum flash_area flash_area;
3064 const struct firmware *fw_entry = NULL;
3065 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3066
3067 if (rmi4_data->sensor_sleep) {
3068 dev_err(rmi4_data->pdev->dev.parent,
3069 "%s: Sensor sleeping\n",
3070 __func__);
3071 return -ENODEV;
3072 }
3073
3074 rmi4_data->stay_awake = true;
3075
3076 pr_notice("%s: Start of reflash process\n", __func__);
3077
3078 if (fwu->image == NULL) {
3079 retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN,
3080 FW_IMAGE_NAME, sizeof(FW_IMAGE_NAME),
3081 sizeof(FW_IMAGE_NAME));
3082 if (retval < 0) {
3083 dev_err(rmi4_data->pdev->dev.parent,
3084 "%s: Failed to copy image file name\n",
3085 __func__);
3086 goto exit;
3087 }
3088 dev_dbg(rmi4_data->pdev->dev.parent,
3089 "%s: Requesting firmware image %s\n",
3090 __func__, fwu->image_name);
3091
3092 retval = request_firmware(&fw_entry, fwu->image_name,
3093 rmi4_data->pdev->dev.parent);
3094 if (retval != 0) {
3095 dev_err(rmi4_data->pdev->dev.parent,
3096 "%s: Firmware image %s not available\n",
3097 __func__, fwu->image_name);
3098 retval = -EINVAL;
3099 goto exit;
3100 }
3101
3102 dev_dbg(rmi4_data->pdev->dev.parent,
3103 "%s: Firmware image size = %d\n",
3104 __func__, fw_entry->size);
3105
3106 fwu->image = fw_entry->data;
3107 }
3108
3109 retval = fwu_parse_image_info();
3110 if (retval < 0)
3111 goto exit;
3112
3113 if (fwu->bl_version != fwu->img.bl_version) {
3114 dev_err(rmi4_data->pdev->dev.parent,
3115 "%s: Bootloader version mismatch\n",
3116 __func__);
3117 retval = -EINVAL;
3118 goto exit;
3119 }
3120
3121 if (!fwu->force_update && fwu->new_partition_table) {
3122 dev_err(rmi4_data->pdev->dev.parent,
3123 "%s: Partition table mismatch\n",
3124 __func__);
3125 retval = -EINVAL;
3126 goto exit;
3127 }
3128
3129 retval = fwu_read_flash_status();
3130 if (retval < 0)
3131 goto exit;
3132
3133 if (fwu->in_bl_mode) {
3134 dev_info(rmi4_data->pdev->dev.parent,
3135 "%s: Device in bootloader mode\n",
3136 __func__);
3137 }
3138
3139 if (fwu->do_lockdown && (fwu->img.lockdown.data != NULL)) {
3140 switch (fwu->bl_version) {
3141 case BL_V5:
3142 case BL_V6:
3143 retval = fwu_do_lockdown();
3144 if (retval < 0) {
3145 dev_err(rmi4_data->pdev->dev.parent,
3146 "%s: Failed to do lockdown\n",
3147 __func__);
3148 }
3149 break;
3150 default:
3151 break;
3152 }
3153 }
3154
3155 flash_area = fwu_go_nogo();
3156
3157 if (flash_area != NONE) {
3158 retval = fwu_enter_flash_prog();
3159 if (retval < 0)
3160 goto reset;
3161 }
3162
3163 switch (flash_area) {
3164 case UI_FIRMWARE:
3165 retval = fwu_do_reflash();
3166 break;
3167 case UI_CONFIG:
3168 retval = fwu_check_ui_configuration_size();
3169 if (retval < 0)
3170 break;
3171 fwu->config_area = UI_CONFIG_AREA;
3172 retval = fwu_erase_configuration();
3173 if (retval < 0)
3174 break;
3175 retval = fwu_write_ui_configuration();
3176 break;
3177 case NONE:
3178 default:
3179 goto reset;
3180 }
3181
3182 if (retval < 0) {
3183 dev_err(rmi4_data->pdev->dev.parent,
3184 "%s: Failed to do reflash\n",
3185 __func__);
3186 }
3187
3188reset:
3189 rmi4_data->reset_device(rmi4_data);
3190
3191exit:
3192 if (fw_entry)
3193 release_firmware(fw_entry);
3194
3195 pr_notice("%s: End of reflash process\n", __func__);
3196
3197 rmi4_data->stay_awake = false;
3198
3199 return retval;
3200}
3201
3202int synaptics_fw_updater(const unsigned char *fw_data)
3203{
3204 int retval;
3205
3206 if (!fwu)
3207 return -ENODEV;
3208
3209 if (!fwu->initialized)
3210 return -ENODEV;
3211
3212 fwu->image = fw_data;
3213
3214 retval = fwu_start_reflash();
3215
3216 fwu->image = NULL;
3217
3218 return retval;
3219}
3220EXPORT_SYMBOL(synaptics_fw_updater);
3221
3222#ifdef DO_STARTUP_FW_UPDATE
3223static void fwu_startup_fw_update_work(struct work_struct *work)
3224{
3225 synaptics_fw_updater(NULL);
3226
3227 return;
3228}
3229#endif
3230
3231static ssize_t fwu_sysfs_show_image(struct file *data_file,
3232 struct kobject *kobj, struct bin_attribute *attributes,
3233 char *buf, loff_t pos, size_t count)
3234{
Peter Leef2bfbf72016-10-24 11:08:09 +08003235 ssize_t retval;
liuyan451acd62015-01-27 10:03:09 +08003236 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3237
Peter Leef2bfbf72016-10-24 11:08:09 +08003238 if (!mutex_trylock(&fwu_sysfs_mutex))
3239 return -EBUSY;
3240
liuyan451acd62015-01-27 10:03:09 +08003241 if (count < fwu->config_size) {
3242 dev_err(rmi4_data->pdev->dev.parent,
3243 "%s: Not enough space (%d bytes) in buffer\n",
3244 __func__, count);
Peter Leef2bfbf72016-10-24 11:08:09 +08003245 retval = -EINVAL;
3246 goto show_image_exit;
liuyan451acd62015-01-27 10:03:09 +08003247 }
3248
3249 retval = secure_memcpy(buf, count, fwu->read_config_buf,
3250 fwu->read_config_buf_size, fwu->config_size);
3251 if (retval < 0) {
3252 dev_err(rmi4_data->pdev->dev.parent,
3253 "%s: Failed to copy config data\n",
3254 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003255 goto show_image_exit;
liuyan451acd62015-01-27 10:03:09 +08003256 }
3257
Peter Leef2bfbf72016-10-24 11:08:09 +08003258 retval = fwu->config_size;
3259
3260show_image_exit:
3261 mutex_unlock(&fwu_sysfs_mutex);
3262 return retval;
liuyan451acd62015-01-27 10:03:09 +08003263}
3264
3265static ssize_t fwu_sysfs_store_image(struct file *data_file,
3266 struct kobject *kobj, struct bin_attribute *attributes,
3267 char *buf, loff_t pos, size_t count)
3268{
Peter Leef2bfbf72016-10-24 11:08:09 +08003269 ssize_t retval;
liuyan451acd62015-01-27 10:03:09 +08003270 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3271
Peter Leef2bfbf72016-10-24 11:08:09 +08003272 if (!mutex_trylock(&fwu_sysfs_mutex))
3273 return -EBUSY;
3274
Peter Leeb9e0cc02016-10-24 14:06:08 +08003275 if (count > (fwu->image_size - fwu->data_pos)) {
3276 dev_err(fwu->rmi4_data->pdev->dev.parent,
3277 "%s: Not enough space in buffer\n",
3278 __func__);
3279 return -EINVAL;
3280 }
3281
liuyan451acd62015-01-27 10:03:09 +08003282 retval = secure_memcpy(&fwu->ext_data_source[fwu->data_pos],
3283 fwu->image_size - fwu->data_pos, buf, count, count);
3284 if (retval < 0) {
3285 dev_err(rmi4_data->pdev->dev.parent,
3286 "%s: Failed to copy image data\n",
3287 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003288 goto store_image_exit;
liuyan451acd62015-01-27 10:03:09 +08003289 }
3290
3291 fwu->data_pos += count;
3292
Peter Leef2bfbf72016-10-24 11:08:09 +08003293 retval = count;
3294
3295store_image_exit:
3296 mutex_unlock(&fwu_sysfs_mutex);
3297 return count;
liuyan451acd62015-01-27 10:03:09 +08003298}
3299
3300static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
3301 struct device_attribute *attr, const char *buf, size_t count)
3302{
Peter Leef2bfbf72016-10-24 11:08:09 +08003303 ssize_t retval;
liuyan451acd62015-01-27 10:03:09 +08003304 unsigned int input;
3305 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3306
Peter Leef2bfbf72016-10-24 11:08:09 +08003307 if (!mutex_trylock(&fwu_sysfs_mutex))
3308 return -EBUSY;
3309
3310 if (!mutex_trylock(&fwu_sysfs_mutex))
3311 return -EBUSY;
3312
liuyan451acd62015-01-27 10:03:09 +08003313 if (sscanf(buf, "%u", &input) != 1) {
3314 retval = -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003315 goto reflash_store_exit;
liuyan451acd62015-01-27 10:03:09 +08003316 }
3317
Peter Leef2bfbf72016-10-24 11:08:09 +08003318 if (!fwu->ext_data_source) {
liuyan451acd62015-01-27 10:03:09 +08003319 return -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003320 goto reflash_store_exit;
3321 } else {
liuyan451acd62015-01-27 10:03:09 +08003322 fwu->image = fwu->ext_data_source;
Peter Leef2bfbf72016-10-24 11:08:09 +08003323 }
liuyan451acd62015-01-27 10:03:09 +08003324
3325 if (input & LOCKDOWN) {
3326 fwu->do_lockdown = true;
3327 input &= ~LOCKDOWN;
3328 }
3329
3330 if ((input != NORMAL) && (input != FORCE)) {
3331 retval = -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003332 goto reflash_store_exit;
liuyan451acd62015-01-27 10:03:09 +08003333 }
3334
3335 if (input == FORCE)
3336 fwu->force_update = true;
3337
3338 retval = synaptics_fw_updater(fwu->image);
3339 if (retval < 0) {
3340 dev_err(rmi4_data->pdev->dev.parent,
3341 "%s: Failed to do reflash\n",
3342 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003343 goto reflash_store_free_exit;
liuyan451acd62015-01-27 10:03:09 +08003344 }
3345
3346 retval = count;
3347
Peter Leef2bfbf72016-10-24 11:08:09 +08003348reflash_store_free_exit:
liuyan451acd62015-01-27 10:03:09 +08003349 kfree(fwu->ext_data_source);
3350 fwu->ext_data_source = NULL;
3351 fwu->image = NULL;
3352 fwu->force_update = FORCE_UPDATE;
3353 fwu->do_lockdown = DO_LOCKDOWN;
Peter Leef2bfbf72016-10-24 11:08:09 +08003354reflash_store_exit:
3355 mutex_unlock(&fwu_sysfs_mutex);
liuyan451acd62015-01-27 10:03:09 +08003356 return retval;
3357}
3358
3359static ssize_t fwu_sysfs_write_config_store(struct device *dev,
3360 struct device_attribute *attr, const char *buf, size_t count)
3361{
3362 int retval;
3363 unsigned int input;
3364 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3365
Peter Leef2bfbf72016-10-24 11:08:09 +08003366 if (!mutex_trylock(&fwu_sysfs_mutex))
3367 return -EBUSY;
3368
liuyan451acd62015-01-27 10:03:09 +08003369 if (sscanf(buf, "%u", &input) != 1) {
3370 retval = -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003371 goto write_config_store_exit;
liuyan451acd62015-01-27 10:03:09 +08003372 }
3373
3374 if (input != 1) {
3375 retval = -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003376 goto write_config_store_exit;
liuyan451acd62015-01-27 10:03:09 +08003377 }
3378
Peter Leef2bfbf72016-10-24 11:08:09 +08003379 if (!fwu->ext_data_source) {
liuyan451acd62015-01-27 10:03:09 +08003380 return -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003381 goto write_config_store_exit;
3382 } else {
liuyan451acd62015-01-27 10:03:09 +08003383 fwu->image = fwu->ext_data_source;
Peter Leef2bfbf72016-10-24 11:08:09 +08003384 }
liuyan451acd62015-01-27 10:03:09 +08003385
3386 retval = fwu_start_write_config();
3387 if (retval < 0) {
3388 dev_err(rmi4_data->pdev->dev.parent,
3389 "%s: Failed to write config\n",
3390 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003391 goto write_config_store_free_exit;
liuyan451acd62015-01-27 10:03:09 +08003392 }
3393
3394 retval = count;
3395
Peter Leef2bfbf72016-10-24 11:08:09 +08003396write_config_store_free_exit:
liuyan451acd62015-01-27 10:03:09 +08003397 kfree(fwu->ext_data_source);
3398 fwu->ext_data_source = NULL;
3399 fwu->image = NULL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003400write_config_store_exit:
3401 mutex_unlock(&fwu_sysfs_mutex);
liuyan451acd62015-01-27 10:03:09 +08003402 return retval;
3403}
3404
3405static ssize_t fwu_sysfs_read_config_store(struct device *dev,
3406 struct device_attribute *attr, const char *buf, size_t count)
3407{
3408 int retval;
3409 unsigned int input;
3410 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3411
3412 if (sscanf(buf, "%u", &input) != 1)
3413 return -EINVAL;
3414
3415 if (input != 1)
3416 return -EINVAL;
3417
Peter Leef2bfbf72016-10-24 11:08:09 +08003418 if (!mutex_trylock(&fwu_sysfs_mutex))
3419 return -EBUSY;
3420
liuyan451acd62015-01-27 10:03:09 +08003421 retval = fwu_do_read_config();
Peter Leef2bfbf72016-10-24 11:08:09 +08003422 mutex_unlock(&fwu_sysfs_mutex);
3423
liuyan451acd62015-01-27 10:03:09 +08003424 if (retval < 0) {
3425 dev_err(rmi4_data->pdev->dev.parent,
3426 "%s: Failed to read config\n",
3427 __func__);
3428 return retval;
3429 }
3430
3431 return count;
3432}
3433
3434static ssize_t fwu_sysfs_config_area_store(struct device *dev,
3435 struct device_attribute *attr, const char *buf, size_t count)
3436{
3437 int retval;
3438 unsigned long config_area;
3439
3440 retval = sstrtoul(buf, 10, &config_area);
3441 if (retval)
3442 return retval;
3443
Peter Leef2bfbf72016-10-24 11:08:09 +08003444 if (!mutex_trylock(&fwu_sysfs_mutex))
3445 return -EBUSY;
3446
liuyan451acd62015-01-27 10:03:09 +08003447 fwu->config_area = config_area;
Peter Leef2bfbf72016-10-24 11:08:09 +08003448 mutex_unlock(&fwu_sysfs_mutex);
liuyan451acd62015-01-27 10:03:09 +08003449
3450 return count;
3451}
3452
3453static ssize_t fwu_sysfs_image_name_store(struct device *dev,
3454 struct device_attribute *attr, const char *buf, size_t count)
3455{
3456 int retval;
3457 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3458
Peter Leef2bfbf72016-10-24 11:08:09 +08003459 if (!mutex_trylock(&fwu_sysfs_mutex))
3460 return -EBUSY;
3461
liuyan451acd62015-01-27 10:03:09 +08003462 retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN,
3463 buf, count, count);
Peter Leef2bfbf72016-10-24 11:08:09 +08003464 mutex_unlock(&fwu_sysfs_mutex);
3465
liuyan451acd62015-01-27 10:03:09 +08003466 if (retval < 0) {
3467 dev_err(rmi4_data->pdev->dev.parent,
3468 "%s: Failed to copy image file name\n",
3469 __func__);
3470 return retval;
3471 }
3472
3473 return count;
3474}
3475
3476static ssize_t fwu_sysfs_image_size_store(struct device *dev,
3477 struct device_attribute *attr, const char *buf, size_t count)
3478{
Peter Leef2bfbf72016-10-24 11:08:09 +08003479 ssize_t retval;
liuyan451acd62015-01-27 10:03:09 +08003480 unsigned long size;
3481 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3482
3483 retval = sstrtoul(buf, 10, &size);
3484 if (retval)
3485 return retval;
3486
Peter Leef2bfbf72016-10-24 11:08:09 +08003487 if (!mutex_trylock(&fwu_sysfs_mutex))
3488 return -EBUSY;
3489
liuyan451acd62015-01-27 10:03:09 +08003490 fwu->image_size = size;
3491 fwu->data_pos = 0;
3492
3493 kfree(fwu->ext_data_source);
3494 fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
3495 if (!fwu->ext_data_source) {
3496 dev_err(rmi4_data->pdev->dev.parent,
3497 "%s: Failed to alloc mem for image data\n",
3498 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003499 retval = -ENOMEM;
3500 } else {
3501 retval = count;
3502 }
liuyan451acd62015-01-27 10:03:09 +08003503
Peter Leef2bfbf72016-10-24 11:08:09 +08003504 mutex_unlock(&fwu_sysfs_mutex);
3505 return retval;
liuyan451acd62015-01-27 10:03:09 +08003506}
3507
3508static ssize_t fwu_sysfs_block_size_show(struct device *dev,
3509 struct device_attribute *attr, char *buf)
3510{
3511 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
3512}
3513
3514static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
3515 struct device_attribute *attr, char *buf)
3516{
3517 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.ui_firmware);
3518}
3519
3520static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
3521 struct device_attribute *attr, char *buf)
3522{
3523 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.ui_config);
3524}
3525
3526static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
3527 struct device_attribute *attr, char *buf)
3528{
3529 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.dp_config);
3530}
3531
3532static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
3533 struct device_attribute *attr, char *buf)
3534{
3535 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.pm_config);
3536}
3537
3538static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
3539 struct device_attribute *attr, char *buf)
3540{
3541 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.bl_config);
3542}
3543
3544static ssize_t fwu_sysfs_guest_code_block_count_show(struct device *dev,
3545 struct device_attribute *attr, char *buf)
3546{
3547 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.guest_code);
3548}
3549
3550static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev,
3551 struct device_attribute *attr, const char *buf, size_t count)
3552{
3553 int retval;
3554 unsigned int input;
3555 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
3556
Peter Leef2bfbf72016-10-24 11:08:09 +08003557 if (!mutex_trylock(&fwu_sysfs_mutex))
3558 return -EBUSY;
3559
liuyan451acd62015-01-27 10:03:09 +08003560 if (sscanf(buf, "%u", &input) != 1) {
3561 retval = -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003562 goto guest_code_store_exit;
liuyan451acd62015-01-27 10:03:09 +08003563 }
3564
3565 if (input != 1) {
3566 retval = -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003567 goto guest_code_store_exit;
liuyan451acd62015-01-27 10:03:09 +08003568 }
3569
Peter Leef2bfbf72016-10-24 11:08:09 +08003570 if (!fwu->ext_data_source) {
liuyan451acd62015-01-27 10:03:09 +08003571 return -EINVAL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003572 goto guest_code_store_exit;
3573 } else {
liuyan451acd62015-01-27 10:03:09 +08003574 fwu->image = fwu->ext_data_source;
Peter Leef2bfbf72016-10-24 11:08:09 +08003575 }
liuyan451acd62015-01-27 10:03:09 +08003576
3577 retval = fwu_start_write_guest_code();
3578 if (retval < 0) {
3579 dev_err(rmi4_data->pdev->dev.parent,
3580 "%s: Failed to write guest code\n",
3581 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003582 goto guest_code_store_free_exit;
liuyan451acd62015-01-27 10:03:09 +08003583 }
3584
3585 retval = count;
3586
Peter Leef2bfbf72016-10-24 11:08:09 +08003587guest_code_store_free_exit:
liuyan451acd62015-01-27 10:03:09 +08003588 kfree(fwu->ext_data_source);
3589 fwu->ext_data_source = NULL;
3590 fwu->image = NULL;
Peter Leef2bfbf72016-10-24 11:08:09 +08003591guest_code_store_exit:
3592 mutex_unlock(&fwu_sysfs_mutex);
liuyan451acd62015-01-27 10:03:09 +08003593 return retval;
3594}
3595
3596static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
3597 unsigned char intr_mask)
3598{
3599 if (!fwu)
3600 return;
3601
3602 if (fwu->intr_mask & intr_mask)
3603 fwu_read_flash_status();
3604
3605 return;
3606}
3607
3608static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
3609{
3610 int retval;
3611 unsigned char attr_count;
3612 struct pdt_properties pdt_props;
3613
3614 fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
3615 if (!fwu) {
3616 dev_err(rmi4_data->pdev->dev.parent,
3617 "%s: Failed to alloc mem for fwu\n",
3618 __func__);
3619 retval = -ENOMEM;
3620 goto exit;
3621 }
3622
3623 fwu->image_name = kzalloc(MAX_IMAGE_NAME_LEN, GFP_KERNEL);
3624 if (!fwu->image_name) {
3625 dev_err(rmi4_data->pdev->dev.parent,
3626 "%s: Failed to alloc mem for image name\n",
3627 __func__);
3628 retval = -ENOMEM;
3629 goto exit_free_fwu;
3630 }
3631
3632 fwu->rmi4_data = rmi4_data;
3633
3634 retval = synaptics_rmi4_reg_read(rmi4_data,
3635 PDT_PROPS,
3636 pdt_props.data,
3637 sizeof(pdt_props.data));
3638 if (retval < 0) {
3639 dev_dbg(rmi4_data->pdev->dev.parent,
3640 "%s: Failed to read PDT properties, assuming 0x00\n",
3641 __func__);
3642 } else if (pdt_props.has_bsr) {
3643 dev_err(rmi4_data->pdev->dev.parent,
3644 "%s: Reflash for LTS not currently supported\n",
3645 __func__);
3646 retval = -ENODEV;
3647 goto exit_free_mem;
3648 }
3649
3650 retval = fwu_scan_pdt();
3651 if (retval < 0)
3652 goto exit_free_mem;
3653
3654 retval = fwu_read_f34_queries();
3655 if (retval < 0)
3656 goto exit_free_mem;
3657
3658 fwu->force_update = FORCE_UPDATE;
3659 fwu->do_lockdown = DO_LOCKDOWN;
3660 fwu->initialized = true;
3661
Peter Leef2bfbf72016-10-24 11:08:09 +08003662#ifdef DO_STARTUP_FW_UPDATE
3663 fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
3664 INIT_WORK(&fwu->fwu_work, fwu_startup_fw_update_work);
3665 queue_work(fwu->fwu_workqueue,
3666 &fwu->fwu_work);
3667#endif
3668
liuyan451acd62015-01-27 10:03:09 +08003669 retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
3670 &dev_attr_data);
3671 if (retval < 0) {
3672 dev_err(rmi4_data->pdev->dev.parent,
3673 "%s: Failed to create sysfs bin file\n",
3674 __func__);
Peter Leef2bfbf72016-10-24 11:08:09 +08003675 goto exit_destroy_work;
liuyan451acd62015-01-27 10:03:09 +08003676 }
3677
3678 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
3679 retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
3680 &attrs[attr_count].attr);
3681 if (retval < 0) {
3682 dev_err(rmi4_data->pdev->dev.parent,
3683 "%s: Failed to create sysfs attributes\n",
3684 __func__);
3685 retval = -ENODEV;
3686 goto exit_remove_attrs;
3687 }
3688 }
3689
liuyan451acd62015-01-27 10:03:09 +08003690 return 0;
3691
3692exit_remove_attrs:
3693 for (attr_count--; attr_count >= 0; attr_count--) {
3694 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
3695 &attrs[attr_count].attr);
3696 }
3697
3698 sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
3699
Peter Leef2bfbf72016-10-24 11:08:09 +08003700exit_destroy_work:
3701#ifdef DO_STARTUP_FW_UPDATE
3702 cancel_work_sync(&fwu->fwu_work);
3703 flush_workqueue(fwu->fwu_workqueue);
3704 destroy_workqueue(fwu->fwu_workqueue);
3705#endif
3706
liuyan451acd62015-01-27 10:03:09 +08003707exit_free_mem:
3708 kfree(fwu->image_name);
3709
3710exit_free_fwu:
3711 kfree(fwu);
3712 fwu = NULL;
3713
3714exit:
3715 return retval;
3716}
3717
3718static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
3719{
3720 unsigned char attr_count;
3721
3722 if (!fwu)
3723 goto exit;
3724
3725#ifdef DO_STARTUP_FW_UPDATE
3726 cancel_work_sync(&fwu->fwu_work);
3727 flush_workqueue(fwu->fwu_workqueue);
3728 destroy_workqueue(fwu->fwu_workqueue);
3729#endif
3730
3731 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
3732 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
3733 &attrs[attr_count].attr);
3734 }
3735
3736 sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
3737
3738 kfree(fwu->read_config_buf);
3739 kfree(fwu->image_name);
3740 kfree(fwu);
3741 fwu = NULL;
3742
3743exit:
3744 complete(&fwu_remove_complete);
3745
3746 return;
3747}
3748
3749static void synaptics_rmi4_fwu_reset(struct synaptics_rmi4_data *rmi4_data)
3750{
3751 if (!fwu) {
3752 synaptics_rmi4_fwu_init(rmi4_data);
3753 return;
3754 }
3755
3756 fwu_scan_pdt();
3757
3758 fwu_read_f34_queries();
3759
3760 return;
3761}
3762
3763static struct synaptics_rmi4_exp_fn fwu_module = {
3764 .fn_type = RMI_FW_UPDATER,
3765 .init = synaptics_rmi4_fwu_init,
3766 .remove = synaptics_rmi4_fwu_remove,
3767 .reset = synaptics_rmi4_fwu_reset,
3768 .reinit = NULL,
3769 .early_suspend = NULL,
3770 .suspend = NULL,
3771 .resume = NULL,
3772 .late_resume = NULL,
3773 .attn = synaptics_rmi4_fwu_attn,
3774};
3775
3776static int __init rmi4_fw_update_module_init(void)
3777{
3778 synaptics_rmi4_new_function(&fwu_module, true);
3779
3780 return 0;
3781}
3782
3783static void __exit rmi4_fw_update_module_exit(void)
3784{
3785 synaptics_rmi4_new_function(&fwu_module, false);
3786
3787 wait_for_completion(&fwu_remove_complete);
3788
3789 return;
3790}
3791
3792module_init(rmi4_fw_update_module_init);
3793module_exit(rmi4_fw_update_module_exit);
3794
3795MODULE_AUTHOR("Synaptics, Inc.");
3796MODULE_DESCRIPTION("Synaptics DSX FW Update Module");
3797MODULE_LICENSE("GPL v2");