blob: 986c062b640057dae3eef4618450649bc144d24c [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 MAX_FIRMWARE_ID_LEN 10
34#define FORCE_UPDATE false
35#define INSIDE_FIRMWARE_UPDATE
Alexandra Chin669d27c2012-12-24 15:42:30 +080036
37#define CHECKSUM_OFFSET 0x00
38#define BOOTLOADER_VERSION_OFFSET 0x07
39#define IMAGE_SIZE_OFFSET 0x08
40#define CONFIG_SIZE_OFFSET 0x0C
41#define PRODUCT_ID_OFFSET 0x10
42#define PRODUCT_INFO_OFFSET 0x1E
43#define FW_IMAGE_OFFSET 0x100
44#define PRODUCT_ID_SIZE 10
45
46#define BOOTLOADER_ID_OFFSET 0
47#define FLASH_PROPERTIES_OFFSET 2
48#define BLOCK_SIZE_OFFSET 3
49#define FW_BLOCK_COUNT_OFFSET 5
50
51#define REG_MAP (1 << 0)
52#define UNLOCKED (1 << 1)
53#define HAS_CONFIG_ID (1 << 2)
54#define HAS_PERM_CONFIG (1 << 3)
55#define HAS_BL_CONFIG (1 << 4)
56#define HAS_DISP_CONFIG (1 << 5)
57#define HAS_CTRL1 (1 << 6)
58
59#define BLOCK_NUMBER_OFFSET 0
60#define BLOCK_DATA_OFFSET 2
61
62#define UI_CONFIG_AREA 0x00
63#define PERM_CONFIG_AREA 0x01
64#define BL_CONFIG_AREA 0x02
65#define DISP_CONFIG_AREA 0x03
66
67enum flash_command {
68 CMD_WRITE_FW_BLOCK = 0x2,
69 CMD_ERASE_ALL = 0x3,
70 CMD_READ_CONFIG_BLOCK = 0x5,
71 CMD_WRITE_CONFIG_BLOCK = 0x6,
72 CMD_ERASE_CONFIG = 0x7,
73 CMD_ERASE_BL_CONFIG = 0x9,
74 CMD_ERASE_DISP_CONFIG = 0xA,
75 CMD_ENABLE_FLASH_PROG = 0xF,
76};
77
Alexandra Chind5591a62013-02-07 12:59:15 -080078enum flash_area {
79 NONE,
80 UI_FIRMWARE,
81 CONFIG_AREA
82};
83
Alexandra Chin669d27c2012-12-24 15:42:30 +080084#define SLEEP_MODE_NORMAL (0x00)
85#define SLEEP_MODE_SENSOR_SLEEP (0x01)
86#define SLEEP_MODE_RESERVED0 (0x02)
87#define SLEEP_MODE_RESERVED1 (0x03)
88
89#define ENABLE_WAIT_MS (1 * 1000)
90#define WRITE_WAIT_MS (3 * 1000)
91#define ERASE_WAIT_MS (5 * 1000)
Alexandra Chind5591a62013-02-07 12:59:15 -080092#define RESET_WAIT_MS (500)
Alexandra Chin669d27c2012-12-24 15:42:30 +080093
Alexandra Chind5591a62013-02-07 12:59:15 -080094#define SLEEP_TIME_US 50
Alexandra Chin669d27c2012-12-24 15:42:30 +080095
96static ssize_t fwu_sysfs_show_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_store_image(struct file *data_file,
101 struct kobject *kobj, struct bin_attribute *attributes,
102 char *buf, loff_t pos, size_t count);
103
104static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
105 struct device_attribute *attr, const char *buf, size_t count);
106
107static ssize_t fwu_sysfs_write_config_store(struct device *dev,
108 struct device_attribute *attr, const char *buf, size_t count);
109
110static ssize_t fwu_sysfs_read_config_store(struct device *dev,
111 struct device_attribute *attr, const char *buf, size_t count);
112
113static ssize_t fwu_sysfs_config_area_store(struct device *dev,
114 struct device_attribute *attr, const char *buf, size_t count);
115
116static ssize_t fwu_sysfs_image_size_store(struct device *dev,
117 struct device_attribute *attr, const char *buf, size_t count);
118
119static ssize_t fwu_sysfs_block_size_show(struct device *dev,
120 struct device_attribute *attr, char *buf);
121
122static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
123 struct device_attribute *attr, char *buf);
124
125static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
126 struct device_attribute *attr, char *buf);
127
128static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
129 struct device_attribute *attr, char *buf);
130
131static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
132 struct device_attribute *attr, char *buf);
133
134static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
135 struct device_attribute *attr, char *buf);
136
Amy Maloched25bd8c2013-01-25 12:34:31 -0800137static ssize_t fwu_sysfs_config_id_show(struct device *dev,
138 struct device_attribute *attr, char *buf);
139
Alexandra Chin669d27c2012-12-24 15:42:30 +0800140static int fwu_wait_for_idle(int timeout_ms);
141
142struct image_header {
143 unsigned int checksum;
144 unsigned int image_size;
145 unsigned int config_size;
146 unsigned char options;
147 unsigned char bootloader_version;
148 unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
149 unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
150};
151
152struct pdt_properties {
153 union {
154 struct {
155 unsigned char reserved_1:6;
156 unsigned char has_bsr:1;
157 unsigned char reserved_2:1;
158 } __packed;
159 unsigned char data[1];
160 };
161};
162
163struct f01_device_status {
164 union {
165 struct {
166 unsigned char status_code:4;
167 unsigned char reserved:2;
168 unsigned char flash_prog:1;
169 unsigned char unconfigured:1;
170 } __packed;
171 unsigned char data[1];
172 };
173};
174
175struct f01_device_control {
176 union {
177 struct {
178 unsigned char sleep_mode:2;
179 unsigned char nosleep:1;
180 unsigned char reserved:2;
181 unsigned char charger_connected:1;
182 unsigned char report_rate:1;
183 unsigned char configured:1;
184 } __packed;
185 unsigned char data[1];
186 };
187};
188
189struct f34_flash_control {
190 union {
191 struct {
192 unsigned char command:4;
193 unsigned char status:3;
194 unsigned char program_enabled:1;
195 } __packed;
196 unsigned char data[1];
197 };
198};
199
200struct f34_flash_properties {
201 union {
202 struct {
203 unsigned char regmap:1;
204 unsigned char unlocked:1;
205 unsigned char has_configid:1;
206 unsigned char has_perm_config:1;
207 unsigned char has_bl_config:1;
208 unsigned char has_display_config:1;
209 unsigned char has_blob_config:1;
210 unsigned char reserved:1;
211 } __packed;
212 unsigned char data[1];
213 };
214};
215
216struct synaptics_rmi4_fwu_handle {
217 bool initialized;
Alexandra Chind5591a62013-02-07 12:59:15 -0800218 bool force_update;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800219 char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
220 unsigned int image_size;
221 unsigned int data_pos;
222 unsigned char intr_mask;
223 unsigned char bootloader_id[2];
224 unsigned char productinfo1;
225 unsigned char productinfo2;
226 unsigned char *ext_data_source;
227 unsigned char *read_config_buf;
228 const unsigned char *firmware_data;
229 const unsigned char *config_data;
230 unsigned short block_size;
231 unsigned short fw_block_count;
232 unsigned short config_block_count;
233 unsigned short perm_config_block_count;
234 unsigned short bl_config_block_count;
235 unsigned short disp_config_block_count;
236 unsigned short config_size;
237 unsigned short config_area;
238 unsigned short addr_f34_flash_control;
239 unsigned short addr_f01_interrupt_register;
240 struct synaptics_rmi4_fn_desc f01_fd;
241 struct synaptics_rmi4_fn_desc f34_fd;
242 struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
243 struct synaptics_rmi4_data *rmi4_data;
244 struct f34_flash_control flash_control;
245 struct f34_flash_properties flash_properties;
Alexandra Chind5591a62013-02-07 12:59:15 -0800246 struct workqueue_struct *fwu_workqueue;
247 struct delayed_work fwu_work;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800248};
249
250static struct bin_attribute dev_attr_data = {
251 .attr = {
252 .name = "data",
253 .mode = (S_IRUGO | S_IWUGO),
254 },
255 .size = 0,
256 .read = fwu_sysfs_show_image,
257 .write = fwu_sysfs_store_image,
258};
259
260static struct device_attribute attrs[] = {
261 __ATTR(doreflash, S_IWUGO,
262 synaptics_rmi4_show_error,
263 fwu_sysfs_do_reflash_store),
264 __ATTR(writeconfig, S_IWUGO,
265 synaptics_rmi4_show_error,
266 fwu_sysfs_write_config_store),
267 __ATTR(readconfig, S_IWUGO,
268 synaptics_rmi4_show_error,
269 fwu_sysfs_read_config_store),
270 __ATTR(configarea, S_IWUGO,
271 synaptics_rmi4_show_error,
272 fwu_sysfs_config_area_store),
273 __ATTR(imagesize, S_IWUGO,
274 synaptics_rmi4_show_error,
275 fwu_sysfs_image_size_store),
276 __ATTR(blocksize, S_IRUGO,
277 fwu_sysfs_block_size_show,
278 synaptics_rmi4_store_error),
279 __ATTR(fwblockcount, S_IRUGO,
280 fwu_sysfs_firmware_block_count_show,
281 synaptics_rmi4_store_error),
282 __ATTR(configblockcount, S_IRUGO,
283 fwu_sysfs_configuration_block_count_show,
284 synaptics_rmi4_store_error),
285 __ATTR(permconfigblockcount, S_IRUGO,
286 fwu_sysfs_perm_config_block_count_show,
287 synaptics_rmi4_store_error),
288 __ATTR(blconfigblockcount, S_IRUGO,
289 fwu_sysfs_bl_config_block_count_show,
290 synaptics_rmi4_store_error),
291 __ATTR(dispconfigblockcount, S_IRUGO,
292 fwu_sysfs_disp_config_block_count_show,
293 synaptics_rmi4_store_error),
Amy Maloched25bd8c2013-01-25 12:34:31 -0800294 __ATTR(config_id, S_IRUGO,
295 fwu_sysfs_config_id_show,
296 synaptics_rmi4_store_error),
Alexandra Chin669d27c2012-12-24 15:42:30 +0800297};
298
299static struct synaptics_rmi4_fwu_handle *fwu;
300
301static struct completion remove_complete;
302
303static unsigned int extract_uint(const unsigned char *ptr)
304{
305 return (unsigned int)ptr[0] +
306 (unsigned int)ptr[1] * 0x100 +
307 (unsigned int)ptr[2] * 0x10000 +
308 (unsigned int)ptr[3] * 0x1000000;
309}
310
311static void parse_header(struct image_header *header,
312 const unsigned char *fw_image)
313{
314 header->checksum = extract_uint(&fw_image[CHECKSUM_OFFSET]);
315 header->bootloader_version = fw_image[BOOTLOADER_VERSION_OFFSET];
316 header->image_size = extract_uint(&fw_image[IMAGE_SIZE_OFFSET]);
317 header->config_size = extract_uint(&fw_image[CONFIG_SIZE_OFFSET]);
318 memcpy(header->product_id, &fw_image[PRODUCT_ID_OFFSET],
319 SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
320 header->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
321 memcpy(header->product_info, &fw_image[PRODUCT_INFO_OFFSET],
322 SYNAPTICS_RMI4_PRODUCT_INFO_SIZE);
323
324#ifdef DEBUG_FW_UPDATE
325 dev_info(&fwu->rmi4_data->i2c_client->dev,
326 "Firwmare size %d, config size %d\n",
327 header->image_size,
328 header->config_size);
329#endif
330 return;
331}
332
Alexandra Chin669d27c2012-12-24 15:42:30 +0800333static int fwu_read_f01_device_status(struct f01_device_status *status)
334{
335 int retval;
336
337 retval = fwu->fn_ptr->read(fwu->rmi4_data,
338 fwu->f01_fd.data_base_addr,
339 status->data,
340 sizeof(status->data));
341 if (retval < 0) {
342 dev_err(&fwu->rmi4_data->i2c_client->dev,
343 "%s: Failed to read F01 device status\n",
344 __func__);
345 return retval;
346 }
347
348 return 0;
349}
350
351static int fwu_read_f34_queries(void)
352{
353 int retval;
354 unsigned char count = 4;
355 unsigned char buf[10];
356 struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
357
358 retval = fwu->fn_ptr->read(fwu->rmi4_data,
359 fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET,
360 fwu->bootloader_id,
361 sizeof(fwu->bootloader_id));
362 if (retval < 0) {
363 dev_err(&i2c_client->dev,
364 "%s: Failed to read bootloader ID\n",
365 __func__);
366 return retval;
367 }
368
369 retval = fwu->fn_ptr->read(fwu->rmi4_data,
370 fwu->f34_fd.query_base_addr + FLASH_PROPERTIES_OFFSET,
371 fwu->flash_properties.data,
372 sizeof(fwu->flash_properties.data));
373 if (retval < 0) {
374 dev_err(&i2c_client->dev,
375 "%s: Failed to read flash properties\n",
376 __func__);
377 return retval;
378 }
379
Alexandra Chind5591a62013-02-07 12:59:15 -0800380 dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n",
Alexandra Chin669d27c2012-12-24 15:42:30 +0800381 __func__,
382 fwu->flash_properties.has_perm_config,
383 fwu->flash_properties.has_bl_config,
384 fwu->flash_properties.has_display_config);
385
386 if (fwu->flash_properties.has_perm_config)
387 count += 2;
388
389 if (fwu->flash_properties.has_bl_config)
390 count += 2;
391
392 if (fwu->flash_properties.has_display_config)
393 count += 2;
394
395 retval = fwu->fn_ptr->read(fwu->rmi4_data,
396 fwu->f34_fd.query_base_addr + BLOCK_SIZE_OFFSET,
397 buf,
398 2);
399 if (retval < 0) {
400 dev_err(&i2c_client->dev,
401 "%s: Failed to read block size info\n",
402 __func__);
403 return retval;
404 }
405
406 batohs(&fwu->block_size, &(buf[0]));
407
408 retval = fwu->fn_ptr->read(fwu->rmi4_data,
409 fwu->f34_fd.query_base_addr + FW_BLOCK_COUNT_OFFSET,
410 buf,
411 count);
412 if (retval < 0) {
413 dev_err(&i2c_client->dev,
414 "%s: Failed to read block count info\n",
415 __func__);
416 return retval;
417 }
418
419 batohs(&fwu->fw_block_count, &(buf[0]));
420 batohs(&fwu->config_block_count, &(buf[2]));
421
422 count = 4;
423
424 if (fwu->flash_properties.has_perm_config) {
425 batohs(&fwu->perm_config_block_count, &(buf[count]));
426 count += 2;
427 }
428
429 if (fwu->flash_properties.has_bl_config) {
430 batohs(&fwu->bl_config_block_count, &(buf[count]));
431 count += 2;
432 }
433
434 if (fwu->flash_properties.has_display_config)
435 batohs(&fwu->disp_config_block_count, &(buf[count]));
436
437 fwu->addr_f34_flash_control = fwu->f34_fd.data_base_addr +
438 BLOCK_DATA_OFFSET +
439 fwu->block_size;
440 return 0;
441}
442
443static int fwu_read_interrupt_status(void)
444{
445 int retval;
446 unsigned char interrupt_status;
447 retval = fwu->fn_ptr->read(fwu->rmi4_data,
448 fwu->addr_f01_interrupt_register,
449 &interrupt_status,
450 sizeof(interrupt_status));
451 if (retval < 0) {
452 dev_err(&fwu->rmi4_data->i2c_client->dev,
453 "%s: Failed to read flash status\n",
454 __func__);
455 return retval;
456 }
457 return interrupt_status;
458}
459
460static int fwu_read_f34_flash_status(void)
461{
462 int retval;
463 retval = fwu->fn_ptr->read(fwu->rmi4_data,
464 fwu->addr_f34_flash_control,
465 fwu->flash_control.data,
466 sizeof(fwu->flash_control.data));
467 if (retval < 0) {
468 dev_err(&fwu->rmi4_data->i2c_client->dev,
469 "%s: Failed to read flash status\n",
470 __func__);
471 return retval;
472 }
473 return 0;
474}
475
476static int fwu_reset_device(void)
477{
478 int retval;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800479
480#ifdef DEBUG_FW_UPDATE
Alexandra Chind5591a62013-02-07 12:59:15 -0800481 dev_info(&fwu->rmi4_data->i2c_client->dev,
482 "%s: Reset device\n",
483 __func__);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800484#endif
485
Alexandra Chin669d27c2012-12-24 15:42:30 +0800486 retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
487 if (retval < 0) {
488 dev_err(&fwu->rmi4_data->i2c_client->dev,
489 "%s: Failed to reset core driver after reflash\n",
490 __func__);
491 return retval;
492 }
493 return 0;
494}
495
496static int fwu_write_f34_command(unsigned char cmd)
497{
498 int retval;
499
Alexandra Chind5591a62013-02-07 12:59:15 -0800500 fwu->flash_control.data[0] = cmd;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800501 retval = fwu->fn_ptr->write(fwu->rmi4_data,
502 fwu->addr_f34_flash_control,
Alexandra Chind5591a62013-02-07 12:59:15 -0800503 fwu->flash_control.data,
504 sizeof(fwu->flash_control.data));
Alexandra Chin669d27c2012-12-24 15:42:30 +0800505 if (retval < 0) {
506 dev_err(&fwu->rmi4_data->i2c_client->dev,
507 "%s: Failed to write command 0x%02x\n",
Alexandra Chind5591a62013-02-07 12:59:15 -0800508 __func__, fwu->flash_control.data[0]);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800509 return retval;
510 }
511 return 0;
512}
513
Alexandra Chin669d27c2012-12-24 15:42:30 +0800514static int fwu_wait_for_idle(int timeout_ms)
515{
516 int count = 0;
Alexandra Chind5591a62013-02-07 12:59:15 -0800517 int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800518 do {
Alexandra Chind5591a62013-02-07 12:59:15 -0800519 if (fwu->flash_control.command == 0x00)
Alexandra Chin669d27c2012-12-24 15:42:30 +0800520 return 0;
521
Alexandra Chind5591a62013-02-07 12:59:15 -0800522 usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 100);
523 } while (count++ < timeout_count);
524
525 fwu_read_f34_flash_status();
526 if (fwu->flash_control.command == 0x00)
527 return 0;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800528
529 dev_err(&fwu->rmi4_data->i2c_client->dev,
530 "%s: Timed out waiting for idle status\n",
531 __func__);
532
533 return -ETIMEDOUT;
534}
535
Alexandra Chind5591a62013-02-07 12:59:15 -0800536static enum flash_area fwu_go_nogo(void)
537{
538 int retval = 0;
539 int index = 0;
540 int deviceFirmwareID;
541 int imageConfigID;
542 int deviceConfigID;
543 unsigned long imageFirmwareID;
544 unsigned char firmware_id[4];
545 unsigned char config_id[4];
546 char *strptr;
547 char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
548 enum flash_area flash_area = NONE;
549 struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
550 struct f01_device_status f01_device_status;
551
552 if (fwu->force_update) {
553 flash_area = UI_FIRMWARE;
554 goto exit;
555 }
556
557 retval = fwu_read_f01_device_status(&f01_device_status);
558 if (retval < 0) {
559 flash_area = NONE;
560 goto exit;
561 }
562
Alexandra Chind5591a62013-02-07 12:59:15 -0800563 /* Force update firmware when device is in bootloader mode */
564 if (f01_device_status.flash_prog) {
565 dev_info(&i2c_client->dev,
566 "%s: In flash prog mode\n",
567 __func__);
568 flash_area = UI_FIRMWARE;
569 goto exit;
570 }
571
572
573 /* device firmware id */
574 retval = fwu->fn_ptr->read(fwu->rmi4_data,
575 fwu->f01_fd.query_base_addr + 18,
576 firmware_id,
577 sizeof(firmware_id));
578 if (retval < 0) {
579 dev_err(&i2c_client->dev,
580 "Failed to read firmware ID (code %d).\n", retval);
581 goto exit;
582 }
583 firmware_id[3] = 0;
584 deviceFirmwareID = extract_uint(firmware_id);
585
586 /* .img firmware id */
Amy Malochecb835832013-03-26 18:06:05 -0700587 strptr = strnstr(fwu->rmi4_data->fw_image_name, "PR",
588 sizeof(fwu->rmi4_data->fw_image_name));
Alexandra Chind5591a62013-02-07 12:59:15 -0800589 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
Amy Malochecb835832013-03-26 18:06:05 -07001222 if (!fwu->rmi4_data->fw_image_name) {
1223 retval = 0;
1224 dev_err(&fwu->rmi4_data->i2c_client->dev,
1225 "Firmware image name not given, skipping update\n");
1226 goto exit;
1227 }
1228
Alexandra Chind5591a62013-02-07 12:59:15 -08001229 if (fwu->ext_data_source)
1230 fw_image = fwu->ext_data_source;
1231 else {
1232 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1233 "%s: Requesting firmware image %s\n",
Amy Malochecb835832013-03-26 18:06:05 -07001234 __func__, fwu->rmi4_data->fw_image_name);
Alexandra Chind5591a62013-02-07 12:59:15 -08001235
Amy Malochecb835832013-03-26 18:06:05 -07001236 retval = request_firmware(&fw_entry,
1237 fwu->rmi4_data->fw_image_name,
Alexandra Chind5591a62013-02-07 12:59:15 -08001238 &fwu->rmi4_data->i2c_client->dev);
1239 if (retval != 0) {
1240 dev_err(&fwu->rmi4_data->i2c_client->dev,
1241 "%s: Firmware image %s not available\n",
Amy Malochecb835832013-03-26 18:06:05 -07001242 __func__,
1243 fwu->rmi4_data->fw_image_name);
Alexandra Chind5591a62013-02-07 12:59:15 -08001244 retval = -EINVAL;
1245 goto exit;
1246 }
1247
1248 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1249 "%s: Firmware image size = %d\n",
1250 __func__, fw_entry->size);
1251
1252 fw_image = fw_entry->data;
1253 }
1254
1255 parse_header(&header, fw_image);
1256
1257 if (header.image_size)
1258 fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
1259 if (header.config_size) {
1260 fwu->config_data = fw_image + FW_IMAGE_OFFSET +
1261 header.image_size;
1262 }
1263
1264 if (fwu->ext_data_source)
1265 flash_area = UI_FIRMWARE;
1266 else
1267 flash_area = fwu_go_nogo();
1268
1269 switch (flash_area) {
1270 case NONE:
1271 dev_info(&fwu->rmi4_data->i2c_client->dev,
1272 "%s: No need to do reflash.\n",
1273 __func__);
1274 goto exit;
1275 case UI_FIRMWARE:
1276 retval = fwu_do_reflash();
1277 break;
1278 case CONFIG_AREA:
1279 retval = fwu_do_write_config();
1280 break;
1281 default:
1282 dev_err(&fwu->rmi4_data->i2c_client->dev,
1283 "%s: Unknown flash area\n",
1284 __func__);
1285 goto exit;
1286 }
1287
1288 if (retval < 0) {
1289 dev_err(&fwu->rmi4_data->i2c_client->dev,
1290 "%s: Failed to do reflash\n",
1291 __func__);
1292 }
1293
1294 /* reset device */
1295 fwu_reset_device();
1296
1297 /* check device status */
1298 retval = fwu_read_f01_device_status(&f01_device_status);
1299 if (retval < 0)
1300 goto exit;
1301
1302 dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
1303 f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
1304 if (f01_device_status.flash_prog)
1305 dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
1306 f01_device_status.status_code);
1307
1308 if (f01_device_status.flash_prog) {
1309 dev_info(&fwu->rmi4_data->i2c_client->dev,
1310 "%s: Device is in flash prog mode 0x%02X\n",
1311 __func__, f01_device_status.status_code);
1312 retval = 0;
1313 goto exit;
1314 }
1315
1316 if (fw_entry)
1317 release_firmware(fw_entry);
1318
1319 pr_notice("%s: End of reflash process\n", __func__);
1320exit:
1321 return retval;
1322}
1323
Alexandra Chin669d27c2012-12-24 15:42:30 +08001324int synaptics_fw_updater(unsigned char *fw_data)
1325{
1326 int retval;
1327
1328 if (!fwu)
1329 return -ENODEV;
1330
1331 if (!fwu->initialized)
1332 return -ENODEV;
1333
1334 fwu->ext_data_source = fw_data;
1335 fwu->config_area = UI_CONFIG_AREA;
1336
1337 retval = fwu_start_reflash();
1338
1339 return retval;
1340}
1341EXPORT_SYMBOL(synaptics_fw_updater);
1342
1343static ssize_t fwu_sysfs_show_image(struct file *data_file,
1344 struct kobject *kobj, struct bin_attribute *attributes,
1345 char *buf, loff_t pos, size_t count)
1346{
1347 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1348
1349 if (count < fwu->config_size) {
1350 dev_err(&rmi4_data->i2c_client->dev,
1351 "%s: Not enough space (%d bytes) in buffer\n",
1352 __func__, count);
1353 return -EINVAL;
1354 }
1355
1356 memcpy(buf, fwu->read_config_buf, fwu->config_size);
1357
1358 return fwu->config_size;
1359}
1360
1361static ssize_t fwu_sysfs_store_image(struct file *data_file,
1362 struct kobject *kobj, struct bin_attribute *attributes,
1363 char *buf, loff_t pos, size_t count)
1364{
1365 memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]),
1366 (const void *)buf,
1367 count);
1368
1369 fwu->data_pos += count;
1370
1371 return count;
1372}
1373
1374static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
1375 struct device_attribute *attr, const char *buf, size_t count)
1376{
1377 int retval;
1378 unsigned int input;
1379 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1380
1381 if (sscanf(buf, "%u", &input) != 1) {
1382 retval = -EINVAL;
1383 goto exit;
1384 }
1385
1386 if (input != 1) {
1387 retval = -EINVAL;
1388 goto exit;
1389 }
1390
1391 retval = synaptics_fw_updater(fwu->ext_data_source);
1392 if (retval < 0) {
1393 dev_err(&rmi4_data->i2c_client->dev,
1394 "%s: Failed to do reflash\n",
1395 __func__);
1396 goto exit;
1397 }
1398
1399 retval = count;
1400
1401exit:
1402 kfree(fwu->ext_data_source);
1403 fwu->ext_data_source = NULL;
1404 return retval;
1405}
1406
1407static ssize_t fwu_sysfs_write_config_store(struct device *dev,
1408 struct device_attribute *attr, const char *buf, size_t count)
1409{
1410 int retval;
1411 unsigned int input;
1412 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1413
1414 if (sscanf(buf, "%u", &input) != 1) {
1415 retval = -EINVAL;
1416 goto exit;
1417 }
1418
1419 if (input != 1) {
1420 retval = -EINVAL;
1421 goto exit;
1422 }
1423
1424 retval = fwu_start_write_config();
1425 if (retval < 0) {
1426 dev_err(&rmi4_data->i2c_client->dev,
1427 "%s: Failed to write config\n",
1428 __func__);
1429 goto exit;
1430 }
1431
1432 retval = count;
1433
1434exit:
1435 kfree(fwu->ext_data_source);
1436 fwu->ext_data_source = NULL;
1437 return retval;
1438}
1439
1440static ssize_t fwu_sysfs_read_config_store(struct device *dev,
1441 struct device_attribute *attr, const char *buf, size_t count)
1442{
1443 int retval;
1444 unsigned int input;
1445 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1446
1447 if (sscanf(buf, "%u", &input) != 1)
1448 return -EINVAL;
1449
1450 if (input != 1)
1451 return -EINVAL;
1452
1453 retval = fwu_do_read_config();
1454 if (retval < 0) {
1455 dev_err(&rmi4_data->i2c_client->dev,
1456 "%s: Failed to read config\n",
1457 __func__);
1458 return retval;
1459 }
1460
1461 return count;
1462}
1463
1464static ssize_t fwu_sysfs_config_area_store(struct device *dev,
1465 struct device_attribute *attr, const char *buf, size_t count)
1466{
1467 int retval;
1468 unsigned long config_area;
1469
Shantanu Jain41f0d472013-01-04 12:14:37 +05301470 retval = kstrtoul(buf, 10, &config_area);
Alexandra Chin669d27c2012-12-24 15:42:30 +08001471 if (retval)
1472 return retval;
1473
1474 fwu->config_area = config_area;
1475
1476 return count;
1477}
1478
1479static ssize_t fwu_sysfs_image_size_store(struct device *dev,
1480 struct device_attribute *attr, const char *buf, size_t count)
1481{
1482 int retval;
1483 unsigned long size;
1484 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1485
Shantanu Jain41f0d472013-01-04 12:14:37 +05301486 retval = kstrtoul(buf, 10, &size);
Alexandra Chin669d27c2012-12-24 15:42:30 +08001487 if (retval)
1488 return retval;
1489
1490 fwu->image_size = size;
1491 fwu->data_pos = 0;
1492
1493 kfree(fwu->ext_data_source);
1494 fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
1495 if (!fwu->ext_data_source) {
1496 dev_err(&rmi4_data->i2c_client->dev,
1497 "%s: Failed to alloc mem for image data\n",
1498 __func__);
1499 return -ENOMEM;
1500 }
1501
1502 return count;
1503}
1504
1505static ssize_t fwu_sysfs_block_size_show(struct device *dev,
1506 struct device_attribute *attr, char *buf)
1507{
1508 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
1509}
1510
1511static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
1512 struct device_attribute *attr, char *buf)
1513{
1514 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count);
1515}
1516
1517static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
1518 struct device_attribute *attr, char *buf)
1519{
1520 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count);
1521}
1522
1523static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
1524 struct device_attribute *attr, char *buf)
1525{
1526 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count);
1527}
1528
1529static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
1530 struct device_attribute *attr, char *buf)
1531{
1532 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count);
1533}
1534
1535static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
1536 struct device_attribute *attr, char *buf)
1537{
1538 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
1539}
1540
Amy Maloched25bd8c2013-01-25 12:34:31 -08001541static ssize_t fwu_sysfs_config_id_show(struct device *dev,
1542 struct device_attribute *attr, char *buf)
1543{
Amy Maloche581f7402013-02-19 16:29:37 -08001544 unsigned char config_id[4];
Amy Maloched25bd8c2013-01-25 12:34:31 -08001545 /* device config id */
1546 fwu->fn_ptr->read(fwu->rmi4_data,
1547 fwu->f34_fd.ctrl_base_addr,
1548 config_id,
1549 sizeof(config_id));
1550
1551 return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
1552 config_id[0], config_id[1], config_id[2], config_id[3]);
1553}
1554
Alexandra Chin669d27c2012-12-24 15:42:30 +08001555static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
1556 unsigned char intr_mask)
1557{
1558 if (fwu->intr_mask & intr_mask)
1559 fwu_read_f34_flash_status();
1560
1561 return;
1562}
1563
Alexandra Chind5591a62013-02-07 12:59:15 -08001564static void synaptics_rmi4_fwu_work(struct work_struct *work)
1565{
1566 fwu_start_reflash();
1567}
1568
Alexandra Chin669d27c2012-12-24 15:42:30 +08001569static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
1570{
1571 int retval;
1572 unsigned char attr_count;
1573 struct pdt_properties pdt_props;
1574
1575 fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
1576 if (!fwu) {
1577 dev_err(&rmi4_data->i2c_client->dev,
1578 "%s: Failed to alloc mem for fwu\n",
1579 __func__);
1580 goto exit;
1581 }
1582
1583 fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL);
1584 if (!fwu->fn_ptr) {
1585 dev_err(&rmi4_data->i2c_client->dev,
1586 "%s: Failed to alloc mem for fn_ptr\n",
1587 __func__);
1588 retval = -ENOMEM;
1589 goto exit_free_fwu;
1590 }
1591
1592 fwu->rmi4_data = rmi4_data;
1593 fwu->fn_ptr->read = rmi4_data->i2c_read;
1594 fwu->fn_ptr->write = rmi4_data->i2c_write;
1595 fwu->fn_ptr->enable = rmi4_data->irq_enable;
1596
1597 retval = fwu->fn_ptr->read(rmi4_data,
1598 PDT_PROPS,
1599 pdt_props.data,
1600 sizeof(pdt_props.data));
1601 if (retval < 0) {
1602 dev_dbg(&rmi4_data->i2c_client->dev,
1603 "%s: Failed to read PDT properties, assuming 0x00\n",
1604 __func__);
1605 } else if (pdt_props.has_bsr) {
1606 dev_err(&rmi4_data->i2c_client->dev,
1607 "%s: Reflash for LTS not currently supported\n",
1608 __func__);
1609 goto exit_free_mem;
1610 }
1611
1612 retval = fwu_scan_pdt();
1613 if (retval < 0)
1614 goto exit_free_mem;
1615
1616 fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0];
1617 fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1];
1618
1619 memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string,
1620 SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
1621 fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
1622
1623 dev_dbg(&rmi4_data->i2c_client->dev,
1624 "%s: F01 product info: 0x%04x 0x%04x\n",
1625 __func__, fwu->productinfo1, fwu->productinfo2);
1626 dev_dbg(&rmi4_data->i2c_client->dev,
1627 "%s: F01 product ID: %s\n",
1628 __func__, fwu->product_id);
1629
1630 retval = fwu_read_f34_queries();
1631 if (retval < 0)
1632 goto exit_free_mem;
1633
1634 fwu->initialized = true;
Alexandra Chind5591a62013-02-07 12:59:15 -08001635 fwu->force_update = FORCE_UPDATE;
Alexandra Chin669d27c2012-12-24 15:42:30 +08001636
1637 retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
1638 &dev_attr_data);
1639 if (retval < 0) {
1640 dev_err(&rmi4_data->i2c_client->dev,
1641 "%s: Failed to create sysfs bin file\n",
1642 __func__);
1643 goto exit_free_mem;
1644 }
1645
1646 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
1647 retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
1648 &attrs[attr_count].attr);
1649 if (retval < 0) {
1650 dev_err(&rmi4_data->i2c_client->dev,
1651 "%s: Failed to create sysfs attributes\n",
1652 __func__);
1653 retval = -ENODEV;
1654 goto exit_remove_attrs;
1655 }
1656 }
1657
Alexandra Chind5591a62013-02-07 12:59:15 -08001658#ifdef INSIDE_FIRMWARE_UPDATE
1659 fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
1660 INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
1661 queue_delayed_work(fwu->fwu_workqueue,
1662 &fwu->fwu_work,
1663 msecs_to_jiffies(1000));
1664#endif
Alexandra Chinc556cf02013-03-19 17:46:05 -07001665
1666 init_completion(&remove_complete);
1667
Alexandra Chin669d27c2012-12-24 15:42:30 +08001668 return 0;
1669
1670exit_remove_attrs:
1671for (attr_count--; attr_count >= 0; attr_count--) {
1672 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
1673 &attrs[attr_count].attr);
1674}
1675
1676sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
1677
1678exit_free_mem:
1679 kfree(fwu->fn_ptr);
1680
1681exit_free_fwu:
1682 kfree(fwu);
1683
1684exit:
1685 return 0;
1686}
1687
1688static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
1689{
1690 unsigned char attr_count;
1691
1692 sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
1693
1694 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
1695 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
1696 &attrs[attr_count].attr);
1697 }
1698
1699 kfree(fwu->fn_ptr);
1700 kfree(fwu);
1701
1702 complete(&remove_complete);
1703
1704 return;
1705}
1706
1707static int __init rmi4_fw_update_module_init(void)
1708{
1709 synaptics_rmi4_new_function(RMI_FW_UPDATER, true,
1710 synaptics_rmi4_fwu_init,
1711 synaptics_rmi4_fwu_remove,
1712 synaptics_rmi4_fwu_attn);
1713 return 0;
1714}
1715
1716static void __exit rmi4_fw_update_module_exit(void)
1717{
Alexandra Chin669d27c2012-12-24 15:42:30 +08001718 synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
1719 synaptics_rmi4_fwu_init,
1720 synaptics_rmi4_fwu_remove,
1721 synaptics_rmi4_fwu_attn);
1722 wait_for_completion(&remove_complete);
1723 return;
1724}
1725
1726module_init(rmi4_fw_update_module_init);
1727module_exit(rmi4_fw_update_module_exit);
1728
1729MODULE_AUTHOR("Synaptics, Inc.");
1730MODULE_DESCRIPTION("RMI4 FW Update Module");
Alexandra Chinbd1dac22013-02-22 12:33:19 -08001731MODULE_LICENSE("GPL v2");