blob: 5d66241c814c2bd8bcff35752f9526fa5090bc9d [file] [log] [blame]
Alexandra Chin669d27c2012-12-24 15:42:30 +08001/*
2 * Synaptics RMI4 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
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/i2c.h>
24#include <linux/interrupt.h>
25#include <linux/delay.h>
26#include <linux/input.h>
27#include <linux/firmware.h>
28#include <linux/input/synaptics_dsx.h>
29#include "synaptics_i2c_rmi4.h"
30
31#define DEBUG_FW_UPDATE
32#define SHOW_PROGRESS
Alexandra Chind5591a62013-02-07 12:59:15 -080033#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
34#define MAX_FIRMWARE_ID_LEN 10
35#define FORCE_UPDATE false
36#define INSIDE_FIRMWARE_UPDATE
Alexandra Chin669d27c2012-12-24 15:42:30 +080037
38#define CHECKSUM_OFFSET 0x00
39#define BOOTLOADER_VERSION_OFFSET 0x07
40#define IMAGE_SIZE_OFFSET 0x08
41#define CONFIG_SIZE_OFFSET 0x0C
42#define PRODUCT_ID_OFFSET 0x10
43#define PRODUCT_INFO_OFFSET 0x1E
44#define FW_IMAGE_OFFSET 0x100
45#define PRODUCT_ID_SIZE 10
46
47#define BOOTLOADER_ID_OFFSET 0
48#define FLASH_PROPERTIES_OFFSET 2
49#define BLOCK_SIZE_OFFSET 3
50#define FW_BLOCK_COUNT_OFFSET 5
51
52#define REG_MAP (1 << 0)
53#define UNLOCKED (1 << 1)
54#define HAS_CONFIG_ID (1 << 2)
55#define HAS_PERM_CONFIG (1 << 3)
56#define HAS_BL_CONFIG (1 << 4)
57#define HAS_DISP_CONFIG (1 << 5)
58#define HAS_CTRL1 (1 << 6)
59
60#define BLOCK_NUMBER_OFFSET 0
61#define BLOCK_DATA_OFFSET 2
62
63#define UI_CONFIG_AREA 0x00
64#define PERM_CONFIG_AREA 0x01
65#define BL_CONFIG_AREA 0x02
66#define DISP_CONFIG_AREA 0x03
67
68enum flash_command {
69 CMD_WRITE_FW_BLOCK = 0x2,
70 CMD_ERASE_ALL = 0x3,
71 CMD_READ_CONFIG_BLOCK = 0x5,
72 CMD_WRITE_CONFIG_BLOCK = 0x6,
73 CMD_ERASE_CONFIG = 0x7,
74 CMD_ERASE_BL_CONFIG = 0x9,
75 CMD_ERASE_DISP_CONFIG = 0xA,
76 CMD_ENABLE_FLASH_PROG = 0xF,
77};
78
Alexandra Chind5591a62013-02-07 12:59:15 -080079enum flash_area {
80 NONE,
81 UI_FIRMWARE,
82 CONFIG_AREA
83};
84
Alexandra Chin669d27c2012-12-24 15:42:30 +080085#define SLEEP_MODE_NORMAL (0x00)
86#define SLEEP_MODE_SENSOR_SLEEP (0x01)
87#define SLEEP_MODE_RESERVED0 (0x02)
88#define SLEEP_MODE_RESERVED1 (0x03)
89
90#define ENABLE_WAIT_MS (1 * 1000)
91#define WRITE_WAIT_MS (3 * 1000)
92#define ERASE_WAIT_MS (5 * 1000)
Alexandra Chind5591a62013-02-07 12:59:15 -080093#define RESET_WAIT_MS (500)
Alexandra Chin669d27c2012-12-24 15:42:30 +080094
Alexandra Chind5591a62013-02-07 12:59:15 -080095#define SLEEP_TIME_US 50
Alexandra Chin669d27c2012-12-24 15:42:30 +080096
97static ssize_t fwu_sysfs_show_image(struct file *data_file,
98 struct kobject *kobj, struct bin_attribute *attributes,
99 char *buf, loff_t pos, size_t count);
100
101static ssize_t fwu_sysfs_store_image(struct file *data_file,
102 struct kobject *kobj, struct bin_attribute *attributes,
103 char *buf, loff_t pos, size_t count);
104
105static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
106 struct device_attribute *attr, const char *buf, size_t count);
107
108static ssize_t fwu_sysfs_write_config_store(struct device *dev,
109 struct device_attribute *attr, const char *buf, size_t count);
110
111static ssize_t fwu_sysfs_read_config_store(struct device *dev,
112 struct device_attribute *attr, const char *buf, size_t count);
113
114static ssize_t fwu_sysfs_config_area_store(struct device *dev,
115 struct device_attribute *attr, const char *buf, size_t count);
116
117static ssize_t fwu_sysfs_image_size_store(struct device *dev,
118 struct device_attribute *attr, const char *buf, size_t count);
119
120static ssize_t fwu_sysfs_block_size_show(struct device *dev,
121 struct device_attribute *attr, char *buf);
122
123static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
124 struct device_attribute *attr, char *buf);
125
126static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
127 struct device_attribute *attr, char *buf);
128
129static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
130 struct device_attribute *attr, char *buf);
131
132static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
133 struct device_attribute *attr, char *buf);
134
135static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
136 struct device_attribute *attr, char *buf);
137
Amy Maloched25bd8c2013-01-25 12:34:31 -0800138static ssize_t fwu_sysfs_config_id_show(struct device *dev,
139 struct device_attribute *attr, char *buf);
140
Alexandra Chin669d27c2012-12-24 15:42:30 +0800141static int fwu_wait_for_idle(int timeout_ms);
142
143struct image_header {
144 unsigned int checksum;
145 unsigned int image_size;
146 unsigned int config_size;
147 unsigned char options;
148 unsigned char bootloader_version;
149 unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
150 unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
151};
152
153struct pdt_properties {
154 union {
155 struct {
156 unsigned char reserved_1:6;
157 unsigned char has_bsr:1;
158 unsigned char reserved_2:1;
159 } __packed;
160 unsigned char data[1];
161 };
162};
163
164struct f01_device_status {
165 union {
166 struct {
167 unsigned char status_code:4;
168 unsigned char reserved:2;
169 unsigned char flash_prog:1;
170 unsigned char unconfigured:1;
171 } __packed;
172 unsigned char data[1];
173 };
174};
175
176struct f01_device_control {
177 union {
178 struct {
179 unsigned char sleep_mode:2;
180 unsigned char nosleep:1;
181 unsigned char reserved:2;
182 unsigned char charger_connected:1;
183 unsigned char report_rate:1;
184 unsigned char configured:1;
185 } __packed;
186 unsigned char data[1];
187 };
188};
189
190struct f34_flash_control {
191 union {
192 struct {
193 unsigned char command:4;
194 unsigned char status:3;
195 unsigned char program_enabled:1;
196 } __packed;
197 unsigned char data[1];
198 };
199};
200
201struct f34_flash_properties {
202 union {
203 struct {
204 unsigned char regmap:1;
205 unsigned char unlocked:1;
206 unsigned char has_configid:1;
207 unsigned char has_perm_config:1;
208 unsigned char has_bl_config:1;
209 unsigned char has_display_config:1;
210 unsigned char has_blob_config:1;
211 unsigned char reserved:1;
212 } __packed;
213 unsigned char data[1];
214 };
215};
216
217struct synaptics_rmi4_fwu_handle {
218 bool initialized;
Alexandra Chind5591a62013-02-07 12:59:15 -0800219 bool force_update;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800220 char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
221 unsigned int image_size;
222 unsigned int data_pos;
223 unsigned char intr_mask;
224 unsigned char bootloader_id[2];
225 unsigned char productinfo1;
226 unsigned char productinfo2;
227 unsigned char *ext_data_source;
228 unsigned char *read_config_buf;
229 const unsigned char *firmware_data;
230 const unsigned char *config_data;
231 unsigned short block_size;
232 unsigned short fw_block_count;
233 unsigned short config_block_count;
234 unsigned short perm_config_block_count;
235 unsigned short bl_config_block_count;
236 unsigned short disp_config_block_count;
237 unsigned short config_size;
238 unsigned short config_area;
239 unsigned short addr_f34_flash_control;
240 unsigned short addr_f01_interrupt_register;
241 struct synaptics_rmi4_fn_desc f01_fd;
242 struct synaptics_rmi4_fn_desc f34_fd;
243 struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
244 struct synaptics_rmi4_data *rmi4_data;
245 struct f34_flash_control flash_control;
246 struct f34_flash_properties flash_properties;
Alexandra Chind5591a62013-02-07 12:59:15 -0800247 struct workqueue_struct *fwu_workqueue;
248 struct delayed_work fwu_work;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800249};
250
251static struct bin_attribute dev_attr_data = {
252 .attr = {
253 .name = "data",
254 .mode = (S_IRUGO | S_IWUGO),
255 },
256 .size = 0,
257 .read = fwu_sysfs_show_image,
258 .write = fwu_sysfs_store_image,
259};
260
261static struct device_attribute attrs[] = {
262 __ATTR(doreflash, S_IWUGO,
263 synaptics_rmi4_show_error,
264 fwu_sysfs_do_reflash_store),
265 __ATTR(writeconfig, S_IWUGO,
266 synaptics_rmi4_show_error,
267 fwu_sysfs_write_config_store),
268 __ATTR(readconfig, S_IWUGO,
269 synaptics_rmi4_show_error,
270 fwu_sysfs_read_config_store),
271 __ATTR(configarea, S_IWUGO,
272 synaptics_rmi4_show_error,
273 fwu_sysfs_config_area_store),
274 __ATTR(imagesize, S_IWUGO,
275 synaptics_rmi4_show_error,
276 fwu_sysfs_image_size_store),
277 __ATTR(blocksize, S_IRUGO,
278 fwu_sysfs_block_size_show,
279 synaptics_rmi4_store_error),
280 __ATTR(fwblockcount, S_IRUGO,
281 fwu_sysfs_firmware_block_count_show,
282 synaptics_rmi4_store_error),
283 __ATTR(configblockcount, S_IRUGO,
284 fwu_sysfs_configuration_block_count_show,
285 synaptics_rmi4_store_error),
286 __ATTR(permconfigblockcount, S_IRUGO,
287 fwu_sysfs_perm_config_block_count_show,
288 synaptics_rmi4_store_error),
289 __ATTR(blconfigblockcount, S_IRUGO,
290 fwu_sysfs_bl_config_block_count_show,
291 synaptics_rmi4_store_error),
292 __ATTR(dispconfigblockcount, S_IRUGO,
293 fwu_sysfs_disp_config_block_count_show,
294 synaptics_rmi4_store_error),
Amy Maloched25bd8c2013-01-25 12:34:31 -0800295 __ATTR(config_id, S_IRUGO,
296 fwu_sysfs_config_id_show,
297 synaptics_rmi4_store_error),
Alexandra Chin669d27c2012-12-24 15:42:30 +0800298};
299
300static struct synaptics_rmi4_fwu_handle *fwu;
301
302static struct completion remove_complete;
303
304static unsigned int extract_uint(const unsigned char *ptr)
305{
306 return (unsigned int)ptr[0] +
307 (unsigned int)ptr[1] * 0x100 +
308 (unsigned int)ptr[2] * 0x10000 +
309 (unsigned int)ptr[3] * 0x1000000;
310}
311
312static void parse_header(struct image_header *header,
313 const unsigned char *fw_image)
314{
315 header->checksum = extract_uint(&fw_image[CHECKSUM_OFFSET]);
316 header->bootloader_version = fw_image[BOOTLOADER_VERSION_OFFSET];
317 header->image_size = extract_uint(&fw_image[IMAGE_SIZE_OFFSET]);
318 header->config_size = extract_uint(&fw_image[CONFIG_SIZE_OFFSET]);
319 memcpy(header->product_id, &fw_image[PRODUCT_ID_OFFSET],
320 SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
321 header->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
322 memcpy(header->product_info, &fw_image[PRODUCT_INFO_OFFSET],
323 SYNAPTICS_RMI4_PRODUCT_INFO_SIZE);
324
325#ifdef DEBUG_FW_UPDATE
326 dev_info(&fwu->rmi4_data->i2c_client->dev,
327 "Firwmare size %d, config size %d\n",
328 header->image_size,
329 header->config_size);
330#endif
331 return;
332}
333
Alexandra Chin669d27c2012-12-24 15:42:30 +0800334static int fwu_read_f01_device_status(struct f01_device_status *status)
335{
336 int retval;
337
338 retval = fwu->fn_ptr->read(fwu->rmi4_data,
339 fwu->f01_fd.data_base_addr,
340 status->data,
341 sizeof(status->data));
342 if (retval < 0) {
343 dev_err(&fwu->rmi4_data->i2c_client->dev,
344 "%s: Failed to read F01 device status\n",
345 __func__);
346 return retval;
347 }
348
349 return 0;
350}
351
352static int fwu_read_f34_queries(void)
353{
354 int retval;
355 unsigned char count = 4;
356 unsigned char buf[10];
357 struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
358
359 retval = fwu->fn_ptr->read(fwu->rmi4_data,
360 fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET,
361 fwu->bootloader_id,
362 sizeof(fwu->bootloader_id));
363 if (retval < 0) {
364 dev_err(&i2c_client->dev,
365 "%s: Failed to read bootloader ID\n",
366 __func__);
367 return retval;
368 }
369
370 retval = fwu->fn_ptr->read(fwu->rmi4_data,
371 fwu->f34_fd.query_base_addr + FLASH_PROPERTIES_OFFSET,
372 fwu->flash_properties.data,
373 sizeof(fwu->flash_properties.data));
374 if (retval < 0) {
375 dev_err(&i2c_client->dev,
376 "%s: Failed to read flash properties\n",
377 __func__);
378 return retval;
379 }
380
Alexandra Chind5591a62013-02-07 12:59:15 -0800381 dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n",
Alexandra Chin669d27c2012-12-24 15:42:30 +0800382 __func__,
383 fwu->flash_properties.has_perm_config,
384 fwu->flash_properties.has_bl_config,
385 fwu->flash_properties.has_display_config);
386
387 if (fwu->flash_properties.has_perm_config)
388 count += 2;
389
390 if (fwu->flash_properties.has_bl_config)
391 count += 2;
392
393 if (fwu->flash_properties.has_display_config)
394 count += 2;
395
396 retval = fwu->fn_ptr->read(fwu->rmi4_data,
397 fwu->f34_fd.query_base_addr + BLOCK_SIZE_OFFSET,
398 buf,
399 2);
400 if (retval < 0) {
401 dev_err(&i2c_client->dev,
402 "%s: Failed to read block size info\n",
403 __func__);
404 return retval;
405 }
406
407 batohs(&fwu->block_size, &(buf[0]));
408
409 retval = fwu->fn_ptr->read(fwu->rmi4_data,
410 fwu->f34_fd.query_base_addr + FW_BLOCK_COUNT_OFFSET,
411 buf,
412 count);
413 if (retval < 0) {
414 dev_err(&i2c_client->dev,
415 "%s: Failed to read block count info\n",
416 __func__);
417 return retval;
418 }
419
420 batohs(&fwu->fw_block_count, &(buf[0]));
421 batohs(&fwu->config_block_count, &(buf[2]));
422
423 count = 4;
424
425 if (fwu->flash_properties.has_perm_config) {
426 batohs(&fwu->perm_config_block_count, &(buf[count]));
427 count += 2;
428 }
429
430 if (fwu->flash_properties.has_bl_config) {
431 batohs(&fwu->bl_config_block_count, &(buf[count]));
432 count += 2;
433 }
434
435 if (fwu->flash_properties.has_display_config)
436 batohs(&fwu->disp_config_block_count, &(buf[count]));
437
438 fwu->addr_f34_flash_control = fwu->f34_fd.data_base_addr +
439 BLOCK_DATA_OFFSET +
440 fwu->block_size;
441 return 0;
442}
443
444static int fwu_read_interrupt_status(void)
445{
446 int retval;
447 unsigned char interrupt_status;
448 retval = fwu->fn_ptr->read(fwu->rmi4_data,
449 fwu->addr_f01_interrupt_register,
450 &interrupt_status,
451 sizeof(interrupt_status));
452 if (retval < 0) {
453 dev_err(&fwu->rmi4_data->i2c_client->dev,
454 "%s: Failed to read flash status\n",
455 __func__);
456 return retval;
457 }
458 return interrupt_status;
459}
460
461static int fwu_read_f34_flash_status(void)
462{
463 int retval;
464 retval = fwu->fn_ptr->read(fwu->rmi4_data,
465 fwu->addr_f34_flash_control,
466 fwu->flash_control.data,
467 sizeof(fwu->flash_control.data));
468 if (retval < 0) {
469 dev_err(&fwu->rmi4_data->i2c_client->dev,
470 "%s: Failed to read flash status\n",
471 __func__);
472 return retval;
473 }
474 return 0;
475}
476
477static int fwu_reset_device(void)
478{
479 int retval;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800480
481#ifdef DEBUG_FW_UPDATE
Alexandra Chind5591a62013-02-07 12:59:15 -0800482 dev_info(&fwu->rmi4_data->i2c_client->dev,
483 "%s: Reset device\n",
484 __func__);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800485#endif
486
Alexandra Chin669d27c2012-12-24 15:42:30 +0800487 retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
488 if (retval < 0) {
489 dev_err(&fwu->rmi4_data->i2c_client->dev,
490 "%s: Failed to reset core driver after reflash\n",
491 __func__);
492 return retval;
493 }
494 return 0;
495}
496
497static int fwu_write_f34_command(unsigned char cmd)
498{
499 int retval;
500
Alexandra Chind5591a62013-02-07 12:59:15 -0800501 fwu->flash_control.data[0] = cmd;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800502 retval = fwu->fn_ptr->write(fwu->rmi4_data,
503 fwu->addr_f34_flash_control,
Alexandra Chind5591a62013-02-07 12:59:15 -0800504 fwu->flash_control.data,
505 sizeof(fwu->flash_control.data));
Alexandra Chin669d27c2012-12-24 15:42:30 +0800506 if (retval < 0) {
507 dev_err(&fwu->rmi4_data->i2c_client->dev,
508 "%s: Failed to write command 0x%02x\n",
Alexandra Chind5591a62013-02-07 12:59:15 -0800509 __func__, fwu->flash_control.data[0]);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800510 return retval;
511 }
512 return 0;
513}
514
Alexandra Chin669d27c2012-12-24 15:42:30 +0800515static int fwu_wait_for_idle(int timeout_ms)
516{
517 int count = 0;
Alexandra Chind5591a62013-02-07 12:59:15 -0800518 int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800519 do {
Alexandra Chind5591a62013-02-07 12:59:15 -0800520 if (fwu->flash_control.command == 0x00)
Alexandra Chin669d27c2012-12-24 15:42:30 +0800521 return 0;
522
Alexandra Chind5591a62013-02-07 12:59:15 -0800523 usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 100);
524 } while (count++ < timeout_count);
525
526 fwu_read_f34_flash_status();
527 if (fwu->flash_control.command == 0x00)
528 return 0;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800529
530 dev_err(&fwu->rmi4_data->i2c_client->dev,
531 "%s: Timed out waiting for idle status\n",
532 __func__);
533
534 return -ETIMEDOUT;
535}
536
Alexandra Chind5591a62013-02-07 12:59:15 -0800537static enum flash_area fwu_go_nogo(void)
538{
539 int retval = 0;
540 int index = 0;
541 int deviceFirmwareID;
542 int imageConfigID;
543 int deviceConfigID;
544 unsigned long imageFirmwareID;
545 unsigned char firmware_id[4];
546 unsigned char config_id[4];
547 char *strptr;
548 char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
549 enum flash_area flash_area = NONE;
550 struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
551 struct f01_device_status f01_device_status;
552
553 if (fwu->force_update) {
554 flash_area = UI_FIRMWARE;
555 goto exit;
556 }
557
558 retval = fwu_read_f01_device_status(&f01_device_status);
559 if (retval < 0) {
560 flash_area = NONE;
561 goto exit;
562 }
563
Alexandra Chind5591a62013-02-07 12:59:15 -0800564 /* Force update firmware when device is in bootloader mode */
565 if (f01_device_status.flash_prog) {
566 dev_info(&i2c_client->dev,
567 "%s: In flash prog mode\n",
568 __func__);
569 flash_area = UI_FIRMWARE;
570 goto exit;
571 }
572
573
574 /* device firmware id */
575 retval = fwu->fn_ptr->read(fwu->rmi4_data,
576 fwu->f01_fd.query_base_addr + 18,
577 firmware_id,
578 sizeof(firmware_id));
579 if (retval < 0) {
580 dev_err(&i2c_client->dev,
581 "Failed to read firmware ID (code %d).\n", retval);
582 goto exit;
583 }
584 firmware_id[3] = 0;
585 deviceFirmwareID = extract_uint(firmware_id);
586
587 /* .img firmware id */
588 strptr = strstr(FW_IMAGE_NAME, "PR");
589 if (!strptr) {
590 dev_err(&i2c_client->dev,
591 "No valid PR number (PRxxxxxxx)" \
592 "found in image file name...\n");
593 goto exit;
594 }
595
596 strptr += 2;
597 while (strptr[index] >= '0' && strptr[index] <= '9') {
598 imagePR[index] = strptr[index];
599 index++;
600 }
601 imagePR[index] = 0;
602
Shantanu Jain41f0d472013-01-04 12:14:37 +0530603 retval = kstrtoul(imagePR, 10, &imageFirmwareID);
Alexandra Chind5591a62013-02-07 12:59:15 -0800604 if (retval == -EINVAL) {
605 dev_err(&i2c_client->dev,
606 "invalid image firmware id...\n");
607 goto exit;
608 }
609
610 dev_info(&i2c_client->dev,
611 "Device firmware id %d, .img firmware id %d\n",
612 deviceFirmwareID,
613 (unsigned int)imageFirmwareID);
614 if (imageFirmwareID > deviceFirmwareID) {
615 flash_area = UI_FIRMWARE;
616 goto exit;
Alexandra Chinc556cf02013-03-19 17:46:05 -0700617 } else if (imageFirmwareID < deviceFirmwareID) {
618 flash_area = NONE;
619 dev_info(&i2c_client->dev,
620 "Img fw is older than device fw. Skip fw update.\n");
621 goto exit;
Alexandra Chind5591a62013-02-07 12:59:15 -0800622 }
623
624 /* device config id */
625 retval = fwu->fn_ptr->read(fwu->rmi4_data,
626 fwu->f34_fd.ctrl_base_addr,
627 config_id,
628 sizeof(config_id));
629 if (retval < 0) {
630 dev_err(&i2c_client->dev,
631 "Failed to read config ID (code %d).\n", retval);
632 flash_area = NONE;
633 goto exit;
634 }
635 deviceConfigID = extract_uint(config_id);
636
637 dev_info(&i2c_client->dev,
638 "Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
639 config_id[0], config_id[1], config_id[2], config_id[3]);
640
641 /* .img config id */
642 dev_info(&i2c_client->dev,
643 ".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
644 fwu->config_data[0],
645 fwu->config_data[1],
646 fwu->config_data[2],
647 fwu->config_data[3]);
648 imageConfigID = extract_uint(fwu->config_data);
649
650 if (imageConfigID > deviceConfigID) {
651 flash_area = CONFIG_AREA;
652 goto exit;
653 }
654
655exit:
656 kfree(imagePR);
657 if (flash_area == NONE)
658 dev_info(&i2c_client->dev,
659 "Nothing needs to be updated\n");
660 else
661 dev_info(&i2c_client->dev,
662 "Update %s block\n",
663 flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG");
664 return flash_area;
665}
666
Alexandra Chin669d27c2012-12-24 15:42:30 +0800667static int fwu_scan_pdt(void)
668{
669 int retval;
670 unsigned char ii;
671 unsigned char intr_count = 0;
672 unsigned char intr_off;
673 unsigned char intr_src;
674 unsigned short addr;
675 bool f01found = false;
676 bool f34found = false;
677 struct synaptics_rmi4_fn_desc rmi_fd;
678
679#ifdef DEBUG_FW_UPDATE
680 dev_info(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
681#endif
682
683 for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
684 retval = fwu->fn_ptr->read(fwu->rmi4_data,
685 addr,
686 (unsigned char *)&rmi_fd,
687 sizeof(rmi_fd));
688 if (retval < 0)
689 return retval;
690
691 if (rmi_fd.fn_number) {
692 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
693 "%s: Found F%02x\n",
694 __func__, rmi_fd.fn_number);
695 switch (rmi_fd.fn_number) {
696 case SYNAPTICS_RMI4_F01:
697 f01found = true;
698 fwu->f01_fd = rmi_fd;
699 fwu->addr_f01_interrupt_register =
700 fwu->f01_fd.data_base_addr + 1;
701 break;
702 case SYNAPTICS_RMI4_F34:
703 f34found = true;
704 fwu->f34_fd = rmi_fd;
705 fwu->intr_mask = 0;
706 intr_src = rmi_fd.intr_src_count;
707 intr_off = intr_count % 8;
708 for (ii = intr_off;
709 ii < ((intr_src & MASK_3BIT) +
710 intr_off);
711 ii++)
712 fwu->intr_mask |= 1 << ii;
713 break;
714 }
715 } else
716 break;
717
718 intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
719 }
720
721 if (!f01found || !f34found) {
722 dev_err(&fwu->rmi4_data->i2c_client->dev,
723 "%s: Failed to find both F01 and F34\n",
724 __func__);
725 return -EINVAL;
726 }
727
728 fwu_read_interrupt_status();
729 return 0;
730}
731
732static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt,
733 unsigned char command)
734{
735 int retval;
736 unsigned char block_offset[] = {0, 0};
737 unsigned short block_num;
Alexandra Chind5591a62013-02-07 12:59:15 -0800738 struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800739#ifdef SHOW_PROGRESS
740 unsigned int progress = (command == CMD_WRITE_CONFIG_BLOCK) ?
741 10 : 100;
742#endif
Alexandra Chind5591a62013-02-07 12:59:15 -0800743
744#ifdef DEBUG_FW_UPDATE
745 dev_info(&i2c_client->dev,
746 "%s: Start to update %s blocks\n",
747 __func__,
748 command == CMD_WRITE_CONFIG_BLOCK ?
749 "config" : "firmware");
750#endif
Alexandra Chin669d27c2012-12-24 15:42:30 +0800751 retval = fwu->fn_ptr->write(fwu->rmi4_data,
752 fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
753 block_offset,
754 sizeof(block_offset));
755 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800756 dev_err(&i2c_client->dev,
Alexandra Chin669d27c2012-12-24 15:42:30 +0800757 "%s: Failed to write to block number registers\n",
758 __func__);
759 return retval;
760 }
761
762 for (block_num = 0; block_num < block_cnt; block_num++) {
763#ifdef SHOW_PROGRESS
764 if (block_num % progress == 0)
Alexandra Chind5591a62013-02-07 12:59:15 -0800765 dev_info(&i2c_client->dev,
766 "%s: update %s %3d / %3d\n",
767 __func__,
768 command == CMD_WRITE_CONFIG_BLOCK ?
769 "config" : "firmware",
770 block_num, block_cnt);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800771#endif
772 retval = fwu->fn_ptr->write(fwu->rmi4_data,
773 fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
774 block_ptr,
775 fwu->block_size);
776 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800777 dev_err(&i2c_client->dev,
Alexandra Chin669d27c2012-12-24 15:42:30 +0800778 "%s: Failed to write block data (block %d)\n",
779 __func__, block_num);
780 return retval;
781 }
782
783 retval = fwu_write_f34_command(command);
784 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800785 dev_err(&i2c_client->dev,
Alexandra Chin669d27c2012-12-24 15:42:30 +0800786 "%s: Failed to write command for block %d\n",
787 __func__, block_num);
788 return retval;
789 }
790
791 retval = fwu_wait_for_idle(WRITE_WAIT_MS);
792 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800793 dev_err(&i2c_client->dev,
794 "%s: Failed to wait for idle status (block %d)\n",
795 __func__, block_num);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800796 return retval;
797 }
798
Alexandra Chind5591a62013-02-07 12:59:15 -0800799 if (fwu->flash_control.status != 0x00) {
800 dev_err(&i2c_client->dev,
801 "%s: Flash block %d failed, status 0x%02X\n",
Alexandra Chin669d27c2012-12-24 15:42:30 +0800802 __func__, block_num, retval);
Shantanu Jain41f0d472013-01-04 12:14:37 +0530803 return retval;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800804 }
Alexandra Chind5591a62013-02-07 12:59:15 -0800805
Alexandra Chin669d27c2012-12-24 15:42:30 +0800806 block_ptr += fwu->block_size;
807 }
808#ifdef SHOW_PROGRESS
Alexandra Chind5591a62013-02-07 12:59:15 -0800809 dev_info(&i2c_client->dev,
810 "%s: update %s %3d / %3d\n",
811 __func__,
812 command == CMD_WRITE_CONFIG_BLOCK ?
813 "config" : "firmware",
814 block_cnt, block_cnt);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800815#endif
816 return 0;
817}
818
819static int fwu_write_firmware(void)
820{
821 return fwu_write_blocks((unsigned char *)fwu->firmware_data,
822 fwu->fw_block_count, CMD_WRITE_FW_BLOCK);
823}
824
825static int fwu_write_configuration(void)
826{
827 return fwu_write_blocks((unsigned char *)fwu->config_data,
828 fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK);
829}
830
831static int fwu_write_bootloader_id(void)
832{
833 int retval;
834
835#ifdef DEBUG_FW_UPDATE
Alexandra Chind5591a62013-02-07 12:59:15 -0800836 dev_info(&fwu->rmi4_data->i2c_client->dev,
837 "Write bootloader ID 0x%02X 0x%02X\n",
838 fwu->bootloader_id[0],
839 fwu->bootloader_id[1]);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800840#endif
841 retval = fwu->fn_ptr->write(fwu->rmi4_data,
842 fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
843 fwu->bootloader_id,
844 sizeof(fwu->bootloader_id));
845 if (retval < 0) {
846 dev_err(&fwu->rmi4_data->i2c_client->dev,
847 "%s: Failed to write bootloader ID\n",
848 __func__);
849 return retval;
850 }
851
852 return 0;
853}
854
855static int fwu_enter_flash_prog(void)
856{
857 int retval;
858 struct f01_device_status f01_device_status;
859 struct f01_device_control f01_device_control;
860
861#ifdef DEBUG_FW_UPDATE
862 dev_info(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
863#endif
864 retval = fwu_read_f01_device_status(&f01_device_status);
865 if (retval < 0)
866 return retval;
867
868 if (f01_device_status.flash_prog) {
869 dev_info(&fwu->rmi4_data->i2c_client->dev,
870 "%s: Already in flash prog mode\n",
871 __func__);
872 return 0;
873 }
874
875 retval = fwu_write_bootloader_id();
876 if (retval < 0)
877 return retval;
878
879 retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
880 if (retval < 0)
881 return retval;
882
883 retval = fwu_wait_for_idle(ENABLE_WAIT_MS);
884 if (retval < 0)
885 return retval;
886
Alexandra Chin669d27c2012-12-24 15:42:30 +0800887 retval = fwu_scan_pdt();
888 if (retval < 0)
889 return retval;
890
891 retval = fwu_read_f01_device_status(&f01_device_status);
892 if (retval < 0)
893 return retval;
894
895 if (!f01_device_status.flash_prog) {
896 dev_err(&fwu->rmi4_data->i2c_client->dev,
897 "%s: Not in flash prog mode\n",
898 __func__);
899 return -EINVAL;
900 }
901
902 retval = fwu_read_f34_queries();
903 if (retval < 0)
904 return retval;
905
906 retval = fwu->fn_ptr->read(fwu->rmi4_data,
907 fwu->f01_fd.ctrl_base_addr,
908 f01_device_control.data,
909 sizeof(f01_device_control.data));
910 if (retval < 0) {
911 dev_err(&fwu->rmi4_data->i2c_client->dev,
912 "%s: Failed to read F01 device control\n",
913 __func__);
914 return retval;
915 }
916
917 f01_device_control.nosleep = true;
918 f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
919
920 retval = fwu->fn_ptr->write(fwu->rmi4_data,
921 fwu->f01_fd.ctrl_base_addr,
922 f01_device_control.data,
923 sizeof(f01_device_control.data));
924 if (retval < 0) {
925 dev_err(&fwu->rmi4_data->i2c_client->dev,
926 "%s: Failed to write F01 device control\n",
927 __func__);
928 return retval;
929 }
930
931 return retval;
932}
933
934static int fwu_do_reflash(void)
935{
936 int retval;
937
938 retval = fwu_enter_flash_prog();
939 if (retval < 0)
940 return retval;
941
942 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
943 "%s: Entered flash prog mode\n",
944 __func__);
945
946 retval = fwu_write_bootloader_id();
947 if (retval < 0)
948 return retval;
949
950 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
951 "%s: Bootloader ID written\n",
952 __func__);
953
954 retval = fwu_write_f34_command(CMD_ERASE_ALL);
955 if (retval < 0)
956 return retval;
957
958 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
959 "%s: Erase all command written\n",
960 __func__);
961
962 retval = fwu_wait_for_idle(ERASE_WAIT_MS);
963 if (retval < 0)
964 return retval;
965
Alexandra Chind5591a62013-02-07 12:59:15 -0800966 if (fwu->flash_control.status != 0x00) {
967 dev_err(&fwu->rmi4_data->i2c_client->dev,
968 "%s: Erase all command failed, status 0x%02X\n",
969 __func__, retval);
970 return -1;
971 }
Alexandra Chin669d27c2012-12-24 15:42:30 +0800972
973 if (fwu->firmware_data) {
974 retval = fwu_write_firmware();
975 if (retval < 0)
976 return retval;
977 pr_notice("%s: Firmware programmed\n", __func__);
978 }
979
980 if (fwu->config_data) {
981 retval = fwu_write_configuration();
982 if (retval < 0)
983 return retval;
984 pr_notice("%s: Configuration programmed\n", __func__);
985 }
986
987 return retval;
988}
989
Alexandra Chin669d27c2012-12-24 15:42:30 +0800990static int fwu_do_write_config(void)
991{
992 int retval;
993
994 retval = fwu_enter_flash_prog();
995 if (retval < 0)
996 return retval;
997
998 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
999 "%s: Entered flash prog mode\n",
1000 __func__);
1001
1002 if (fwu->config_area == PERM_CONFIG_AREA) {
1003 fwu->config_block_count = fwu->perm_config_block_count;
1004 goto write_config;
1005 }
1006
1007 retval = fwu_write_bootloader_id();
1008 if (retval < 0)
1009 return retval;
1010
1011 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1012 "%s: Bootloader ID written\n",
1013 __func__);
1014
1015 switch (fwu->config_area) {
1016 case UI_CONFIG_AREA:
1017 retval = fwu_write_f34_command(CMD_ERASE_CONFIG);
1018 break;
1019 case BL_CONFIG_AREA:
1020 retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
1021 fwu->config_block_count = fwu->bl_config_block_count;
1022 break;
1023 case DISP_CONFIG_AREA:
1024 retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
1025 fwu->config_block_count = fwu->disp_config_block_count;
1026 break;
1027 }
1028 if (retval < 0)
1029 return retval;
1030
1031 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1032 "%s: Erase command written\n",
1033 __func__);
1034
1035 retval = fwu_wait_for_idle(ERASE_WAIT_MS);
1036 if (retval < 0)
1037 return retval;
1038
1039 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1040 "%s: Idle status detected\n",
1041 __func__);
1042
1043write_config:
1044 retval = fwu_write_configuration();
1045 if (retval < 0)
1046 return retval;
1047
1048 pr_notice("%s: Config written\n", __func__);
1049
1050 return retval;
1051}
1052
1053static int fwu_start_write_config(void)
1054{
1055 int retval;
1056 struct image_header header;
1057
1058 switch (fwu->config_area) {
1059 case UI_CONFIG_AREA:
1060 break;
1061 case PERM_CONFIG_AREA:
1062 if (!fwu->flash_properties.has_perm_config)
1063 return -EINVAL;
1064 break;
1065 case BL_CONFIG_AREA:
1066 if (!fwu->flash_properties.has_bl_config)
1067 return -EINVAL;
1068 break;
1069 case DISP_CONFIG_AREA:
1070 if (!fwu->flash_properties.has_display_config)
1071 return -EINVAL;
1072 break;
1073 default:
1074 return -EINVAL;
1075 }
1076
1077 if (fwu->ext_data_source)
1078 fwu->config_data = fwu->ext_data_source;
1079 else
1080 return -EINVAL;
1081
1082 if (fwu->config_area == UI_CONFIG_AREA) {
1083 parse_header(&header, fwu->ext_data_source);
1084
1085 if (header.config_size) {
1086 fwu->config_data = fwu->ext_data_source +
1087 FW_IMAGE_OFFSET +
1088 header.image_size;
1089 } else {
1090 return -EINVAL;
1091 }
1092 }
1093
1094 pr_notice("%s: Start of write config process\n", __func__);
1095
1096 retval = fwu_do_write_config();
1097 if (retval < 0) {
1098 dev_err(&fwu->rmi4_data->i2c_client->dev,
1099 "%s: Failed to write config\n",
1100 __func__);
1101 }
1102
1103 fwu->rmi4_data->reset_device(fwu->rmi4_data);
1104
1105 pr_notice("%s: End of write config process\n", __func__);
1106
1107 return retval;
1108}
1109
1110static int fwu_do_read_config(void)
1111{
1112 int retval;
1113 unsigned char block_offset[] = {0, 0};
1114 unsigned short block_num;
1115 unsigned short block_count;
1116 unsigned short index = 0;
1117
1118 retval = fwu_enter_flash_prog();
1119 if (retval < 0)
1120 goto exit;
1121
1122 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1123 "%s: Entered flash prog mode\n",
1124 __func__);
1125
1126 switch (fwu->config_area) {
1127 case UI_CONFIG_AREA:
1128 block_count = fwu->config_block_count;
1129 break;
1130 case PERM_CONFIG_AREA:
1131 if (!fwu->flash_properties.has_perm_config) {
1132 retval = -EINVAL;
1133 goto exit;
1134 }
1135 block_count = fwu->perm_config_block_count;
1136 break;
1137 case BL_CONFIG_AREA:
1138 if (!fwu->flash_properties.has_bl_config) {
1139 retval = -EINVAL;
1140 goto exit;
1141 }
1142 block_count = fwu->bl_config_block_count;
1143 break;
1144 case DISP_CONFIG_AREA:
1145 if (!fwu->flash_properties.has_display_config) {
1146 retval = -EINVAL;
1147 goto exit;
1148 }
1149 block_count = fwu->disp_config_block_count;
1150 break;
1151 default:
1152 retval = -EINVAL;
1153 goto exit;
1154 }
1155
1156 fwu->config_size = fwu->block_size * block_count;
1157
1158 kfree(fwu->read_config_buf);
1159 fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
1160
1161 block_offset[1] |= (fwu->config_area << 5);
1162
1163 retval = fwu->fn_ptr->write(fwu->rmi4_data,
1164 fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
1165 block_offset,
1166 sizeof(block_offset));
1167 if (retval < 0) {
1168 dev_err(&fwu->rmi4_data->i2c_client->dev,
1169 "%s: Failed to write to block number registers\n",
1170 __func__);
1171 goto exit;
1172 }
1173
1174 for (block_num = 0; block_num < block_count; block_num++) {
1175 retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK);
1176 if (retval < 0) {
1177 dev_err(&fwu->rmi4_data->i2c_client->dev,
1178 "%s: Failed to write read config command\n",
1179 __func__);
1180 goto exit;
1181 }
1182
1183 retval = fwu_wait_for_idle(WRITE_WAIT_MS);
1184 if (retval < 0) {
1185 dev_err(&fwu->rmi4_data->i2c_client->dev,
1186 "%s: Failed to wait for idle status\n",
1187 __func__);
1188 goto exit;
1189 }
1190
1191 retval = fwu->fn_ptr->read(fwu->rmi4_data,
1192 fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
1193 &fwu->read_config_buf[index],
1194 fwu->block_size);
1195 if (retval < 0) {
1196 dev_err(&fwu->rmi4_data->i2c_client->dev,
1197 "%s: Failed to read block data (block %d)\n",
1198 __func__, block_num);
1199 goto exit;
1200 }
1201
1202 index += fwu->block_size;
1203 }
1204
1205exit:
1206 fwu->rmi4_data->reset_device(fwu->rmi4_data);
1207
1208 return retval;
1209}
1210
Alexandra Chind5591a62013-02-07 12:59:15 -08001211static int fwu_start_reflash(void)
1212{
1213 int retval;
1214 struct image_header header;
1215 const unsigned char *fw_image;
1216 const struct firmware *fw_entry = NULL;
1217 struct f01_device_status f01_device_status;
1218 enum flash_area flash_area;
1219
1220 pr_notice("%s: Start of reflash process\n", __func__);
1221
1222 if (fwu->ext_data_source)
1223 fw_image = fwu->ext_data_source;
1224 else {
1225 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1226 "%s: Requesting firmware image %s\n",
1227 __func__, FW_IMAGE_NAME);
1228
1229 retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
1230 &fwu->rmi4_data->i2c_client->dev);
1231 if (retval != 0) {
1232 dev_err(&fwu->rmi4_data->i2c_client->dev,
1233 "%s: Firmware image %s not available\n",
1234 __func__, FW_IMAGE_NAME);
1235 retval = -EINVAL;
1236 goto exit;
1237 }
1238
1239 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1240 "%s: Firmware image size = %d\n",
1241 __func__, fw_entry->size);
1242
1243 fw_image = fw_entry->data;
1244 }
1245
1246 parse_header(&header, fw_image);
1247
1248 if (header.image_size)
1249 fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
1250 if (header.config_size) {
1251 fwu->config_data = fw_image + FW_IMAGE_OFFSET +
1252 header.image_size;
1253 }
1254
1255 if (fwu->ext_data_source)
1256 flash_area = UI_FIRMWARE;
1257 else
1258 flash_area = fwu_go_nogo();
1259
1260 switch (flash_area) {
1261 case NONE:
1262 dev_info(&fwu->rmi4_data->i2c_client->dev,
1263 "%s: No need to do reflash.\n",
1264 __func__);
1265 goto exit;
1266 case UI_FIRMWARE:
1267 retval = fwu_do_reflash();
1268 break;
1269 case CONFIG_AREA:
1270 retval = fwu_do_write_config();
1271 break;
1272 default:
1273 dev_err(&fwu->rmi4_data->i2c_client->dev,
1274 "%s: Unknown flash area\n",
1275 __func__);
1276 goto exit;
1277 }
1278
1279 if (retval < 0) {
1280 dev_err(&fwu->rmi4_data->i2c_client->dev,
1281 "%s: Failed to do reflash\n",
1282 __func__);
1283 }
1284
1285 /* reset device */
1286 fwu_reset_device();
1287
1288 /* check device status */
1289 retval = fwu_read_f01_device_status(&f01_device_status);
1290 if (retval < 0)
1291 goto exit;
1292
1293 dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
1294 f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
1295 if (f01_device_status.flash_prog)
1296 dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
1297 f01_device_status.status_code);
1298
1299 if (f01_device_status.flash_prog) {
1300 dev_info(&fwu->rmi4_data->i2c_client->dev,
1301 "%s: Device is in flash prog mode 0x%02X\n",
1302 __func__, f01_device_status.status_code);
1303 retval = 0;
1304 goto exit;
1305 }
1306
1307 if (fw_entry)
1308 release_firmware(fw_entry);
1309
1310 pr_notice("%s: End of reflash process\n", __func__);
1311exit:
1312 return retval;
1313}
1314
Alexandra Chin669d27c2012-12-24 15:42:30 +08001315int synaptics_fw_updater(unsigned char *fw_data)
1316{
1317 int retval;
1318
1319 if (!fwu)
1320 return -ENODEV;
1321
1322 if (!fwu->initialized)
1323 return -ENODEV;
1324
1325 fwu->ext_data_source = fw_data;
1326 fwu->config_area = UI_CONFIG_AREA;
1327
1328 retval = fwu_start_reflash();
1329
1330 return retval;
1331}
1332EXPORT_SYMBOL(synaptics_fw_updater);
1333
1334static ssize_t fwu_sysfs_show_image(struct file *data_file,
1335 struct kobject *kobj, struct bin_attribute *attributes,
1336 char *buf, loff_t pos, size_t count)
1337{
1338 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1339
1340 if (count < fwu->config_size) {
1341 dev_err(&rmi4_data->i2c_client->dev,
1342 "%s: Not enough space (%d bytes) in buffer\n",
1343 __func__, count);
1344 return -EINVAL;
1345 }
1346
1347 memcpy(buf, fwu->read_config_buf, fwu->config_size);
1348
1349 return fwu->config_size;
1350}
1351
1352static ssize_t fwu_sysfs_store_image(struct file *data_file,
1353 struct kobject *kobj, struct bin_attribute *attributes,
1354 char *buf, loff_t pos, size_t count)
1355{
1356 memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]),
1357 (const void *)buf,
1358 count);
1359
1360 fwu->data_pos += count;
1361
1362 return count;
1363}
1364
1365static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
1366 struct device_attribute *attr, const char *buf, size_t count)
1367{
1368 int retval;
1369 unsigned int input;
1370 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1371
1372 if (sscanf(buf, "%u", &input) != 1) {
1373 retval = -EINVAL;
1374 goto exit;
1375 }
1376
1377 if (input != 1) {
1378 retval = -EINVAL;
1379 goto exit;
1380 }
1381
1382 retval = synaptics_fw_updater(fwu->ext_data_source);
1383 if (retval < 0) {
1384 dev_err(&rmi4_data->i2c_client->dev,
1385 "%s: Failed to do reflash\n",
1386 __func__);
1387 goto exit;
1388 }
1389
1390 retval = count;
1391
1392exit:
1393 kfree(fwu->ext_data_source);
1394 fwu->ext_data_source = NULL;
1395 return retval;
1396}
1397
1398static ssize_t fwu_sysfs_write_config_store(struct device *dev,
1399 struct device_attribute *attr, const char *buf, size_t count)
1400{
1401 int retval;
1402 unsigned int input;
1403 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1404
1405 if (sscanf(buf, "%u", &input) != 1) {
1406 retval = -EINVAL;
1407 goto exit;
1408 }
1409
1410 if (input != 1) {
1411 retval = -EINVAL;
1412 goto exit;
1413 }
1414
1415 retval = fwu_start_write_config();
1416 if (retval < 0) {
1417 dev_err(&rmi4_data->i2c_client->dev,
1418 "%s: Failed to write config\n",
1419 __func__);
1420 goto exit;
1421 }
1422
1423 retval = count;
1424
1425exit:
1426 kfree(fwu->ext_data_source);
1427 fwu->ext_data_source = NULL;
1428 return retval;
1429}
1430
1431static ssize_t fwu_sysfs_read_config_store(struct device *dev,
1432 struct device_attribute *attr, const char *buf, size_t count)
1433{
1434 int retval;
1435 unsigned int input;
1436 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1437
1438 if (sscanf(buf, "%u", &input) != 1)
1439 return -EINVAL;
1440
1441 if (input != 1)
1442 return -EINVAL;
1443
1444 retval = fwu_do_read_config();
1445 if (retval < 0) {
1446 dev_err(&rmi4_data->i2c_client->dev,
1447 "%s: Failed to read config\n",
1448 __func__);
1449 return retval;
1450 }
1451
1452 return count;
1453}
1454
1455static ssize_t fwu_sysfs_config_area_store(struct device *dev,
1456 struct device_attribute *attr, const char *buf, size_t count)
1457{
1458 int retval;
1459 unsigned long config_area;
1460
Shantanu Jain41f0d472013-01-04 12:14:37 +05301461 retval = kstrtoul(buf, 10, &config_area);
Alexandra Chin669d27c2012-12-24 15:42:30 +08001462 if (retval)
1463 return retval;
1464
1465 fwu->config_area = config_area;
1466
1467 return count;
1468}
1469
1470static ssize_t fwu_sysfs_image_size_store(struct device *dev,
1471 struct device_attribute *attr, const char *buf, size_t count)
1472{
1473 int retval;
1474 unsigned long size;
1475 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1476
Shantanu Jain41f0d472013-01-04 12:14:37 +05301477 retval = kstrtoul(buf, 10, &size);
Alexandra Chin669d27c2012-12-24 15:42:30 +08001478 if (retval)
1479 return retval;
1480
1481 fwu->image_size = size;
1482 fwu->data_pos = 0;
1483
1484 kfree(fwu->ext_data_source);
1485 fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
1486 if (!fwu->ext_data_source) {
1487 dev_err(&rmi4_data->i2c_client->dev,
1488 "%s: Failed to alloc mem for image data\n",
1489 __func__);
1490 return -ENOMEM;
1491 }
1492
1493 return count;
1494}
1495
1496static ssize_t fwu_sysfs_block_size_show(struct device *dev,
1497 struct device_attribute *attr, char *buf)
1498{
1499 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
1500}
1501
1502static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
1503 struct device_attribute *attr, char *buf)
1504{
1505 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count);
1506}
1507
1508static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
1509 struct device_attribute *attr, char *buf)
1510{
1511 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count);
1512}
1513
1514static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
1515 struct device_attribute *attr, char *buf)
1516{
1517 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count);
1518}
1519
1520static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
1521 struct device_attribute *attr, char *buf)
1522{
1523 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count);
1524}
1525
1526static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
1527 struct device_attribute *attr, char *buf)
1528{
1529 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
1530}
1531
Amy Maloched25bd8c2013-01-25 12:34:31 -08001532static ssize_t fwu_sysfs_config_id_show(struct device *dev,
1533 struct device_attribute *attr, char *buf)
1534{
Amy Maloche581f7402013-02-19 16:29:37 -08001535 unsigned char config_id[4];
Amy Maloched25bd8c2013-01-25 12:34:31 -08001536 /* device config id */
1537 fwu->fn_ptr->read(fwu->rmi4_data,
1538 fwu->f34_fd.ctrl_base_addr,
1539 config_id,
1540 sizeof(config_id));
1541
1542 return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
1543 config_id[0], config_id[1], config_id[2], config_id[3]);
1544}
1545
Alexandra Chin669d27c2012-12-24 15:42:30 +08001546static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
1547 unsigned char intr_mask)
1548{
1549 if (fwu->intr_mask & intr_mask)
1550 fwu_read_f34_flash_status();
1551
1552 return;
1553}
1554
Alexandra Chind5591a62013-02-07 12:59:15 -08001555static void synaptics_rmi4_fwu_work(struct work_struct *work)
1556{
1557 fwu_start_reflash();
1558}
1559
Alexandra Chin669d27c2012-12-24 15:42:30 +08001560static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
1561{
1562 int retval;
1563 unsigned char attr_count;
1564 struct pdt_properties pdt_props;
1565
1566 fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
1567 if (!fwu) {
1568 dev_err(&rmi4_data->i2c_client->dev,
1569 "%s: Failed to alloc mem for fwu\n",
1570 __func__);
1571 goto exit;
1572 }
1573
1574 fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL);
1575 if (!fwu->fn_ptr) {
1576 dev_err(&rmi4_data->i2c_client->dev,
1577 "%s: Failed to alloc mem for fn_ptr\n",
1578 __func__);
1579 retval = -ENOMEM;
1580 goto exit_free_fwu;
1581 }
1582
1583 fwu->rmi4_data = rmi4_data;
1584 fwu->fn_ptr->read = rmi4_data->i2c_read;
1585 fwu->fn_ptr->write = rmi4_data->i2c_write;
1586 fwu->fn_ptr->enable = rmi4_data->irq_enable;
1587
1588 retval = fwu->fn_ptr->read(rmi4_data,
1589 PDT_PROPS,
1590 pdt_props.data,
1591 sizeof(pdt_props.data));
1592 if (retval < 0) {
1593 dev_dbg(&rmi4_data->i2c_client->dev,
1594 "%s: Failed to read PDT properties, assuming 0x00\n",
1595 __func__);
1596 } else if (pdt_props.has_bsr) {
1597 dev_err(&rmi4_data->i2c_client->dev,
1598 "%s: Reflash for LTS not currently supported\n",
1599 __func__);
1600 goto exit_free_mem;
1601 }
1602
1603 retval = fwu_scan_pdt();
1604 if (retval < 0)
1605 goto exit_free_mem;
1606
1607 fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0];
1608 fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1];
1609
1610 memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string,
1611 SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
1612 fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
1613
1614 dev_dbg(&rmi4_data->i2c_client->dev,
1615 "%s: F01 product info: 0x%04x 0x%04x\n",
1616 __func__, fwu->productinfo1, fwu->productinfo2);
1617 dev_dbg(&rmi4_data->i2c_client->dev,
1618 "%s: F01 product ID: %s\n",
1619 __func__, fwu->product_id);
1620
1621 retval = fwu_read_f34_queries();
1622 if (retval < 0)
1623 goto exit_free_mem;
1624
1625 fwu->initialized = true;
Alexandra Chind5591a62013-02-07 12:59:15 -08001626 fwu->force_update = FORCE_UPDATE;
Alexandra Chin669d27c2012-12-24 15:42:30 +08001627
1628 retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
1629 &dev_attr_data);
1630 if (retval < 0) {
1631 dev_err(&rmi4_data->i2c_client->dev,
1632 "%s: Failed to create sysfs bin file\n",
1633 __func__);
1634 goto exit_free_mem;
1635 }
1636
1637 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
1638 retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
1639 &attrs[attr_count].attr);
1640 if (retval < 0) {
1641 dev_err(&rmi4_data->i2c_client->dev,
1642 "%s: Failed to create sysfs attributes\n",
1643 __func__);
1644 retval = -ENODEV;
1645 goto exit_remove_attrs;
1646 }
1647 }
1648
Alexandra Chind5591a62013-02-07 12:59:15 -08001649#ifdef INSIDE_FIRMWARE_UPDATE
1650 fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
1651 INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
1652 queue_delayed_work(fwu->fwu_workqueue,
1653 &fwu->fwu_work,
1654 msecs_to_jiffies(1000));
1655#endif
Alexandra Chinc556cf02013-03-19 17:46:05 -07001656
1657 init_completion(&remove_complete);
1658
Alexandra Chin669d27c2012-12-24 15:42:30 +08001659 return 0;
1660
1661exit_remove_attrs:
1662for (attr_count--; attr_count >= 0; attr_count--) {
1663 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
1664 &attrs[attr_count].attr);
1665}
1666
1667sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
1668
1669exit_free_mem:
1670 kfree(fwu->fn_ptr);
1671
1672exit_free_fwu:
1673 kfree(fwu);
1674
1675exit:
1676 return 0;
1677}
1678
1679static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
1680{
1681 unsigned char attr_count;
1682
1683 sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
1684
1685 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
1686 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
1687 &attrs[attr_count].attr);
1688 }
1689
1690 kfree(fwu->fn_ptr);
1691 kfree(fwu);
1692
1693 complete(&remove_complete);
1694
1695 return;
1696}
1697
1698static int __init rmi4_fw_update_module_init(void)
1699{
1700 synaptics_rmi4_new_function(RMI_FW_UPDATER, true,
1701 synaptics_rmi4_fwu_init,
1702 synaptics_rmi4_fwu_remove,
1703 synaptics_rmi4_fwu_attn);
1704 return 0;
1705}
1706
1707static void __exit rmi4_fw_update_module_exit(void)
1708{
Alexandra Chin669d27c2012-12-24 15:42:30 +08001709 synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
1710 synaptics_rmi4_fwu_init,
1711 synaptics_rmi4_fwu_remove,
1712 synaptics_rmi4_fwu_attn);
1713 wait_for_completion(&remove_complete);
1714 return;
1715}
1716
1717module_init(rmi4_fw_update_module_init);
1718module_exit(rmi4_fw_update_module_exit);
1719
1720MODULE_AUTHOR("Synaptics, Inc.");
1721MODULE_DESCRIPTION("RMI4 FW Update Module");
Alexandra Chinbd1dac22013-02-22 12:33:19 -08001722MODULE_LICENSE("GPL v2");