blob: abb5bbca5924467c7e91b83459d378bc147d002d [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
564 imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
565
566 /* Force update firmware when device is in bootloader mode */
567 if (f01_device_status.flash_prog) {
568 dev_info(&i2c_client->dev,
569 "%s: In flash prog mode\n",
570 __func__);
571 flash_area = UI_FIRMWARE;
572 goto exit;
573 }
574
575
576 /* device firmware id */
577 retval = fwu->fn_ptr->read(fwu->rmi4_data,
578 fwu->f01_fd.query_base_addr + 18,
579 firmware_id,
580 sizeof(firmware_id));
581 if (retval < 0) {
582 dev_err(&i2c_client->dev,
583 "Failed to read firmware ID (code %d).\n", retval);
584 goto exit;
585 }
586 firmware_id[3] = 0;
587 deviceFirmwareID = extract_uint(firmware_id);
588
589 /* .img firmware id */
590 strptr = strstr(FW_IMAGE_NAME, "PR");
591 if (!strptr) {
592 dev_err(&i2c_client->dev,
593 "No valid PR number (PRxxxxxxx)" \
594 "found in image file name...\n");
595 goto exit;
596 }
597
598 strptr += 2;
599 while (strptr[index] >= '0' && strptr[index] <= '9') {
600 imagePR[index] = strptr[index];
601 index++;
602 }
603 imagePR[index] = 0;
604
Shantanu Jain41f0d472013-01-04 12:14:37 +0530605 retval = kstrtoul(imagePR, 10, &imageFirmwareID);
Alexandra Chind5591a62013-02-07 12:59:15 -0800606 if (retval == -EINVAL) {
607 dev_err(&i2c_client->dev,
608 "invalid image firmware id...\n");
609 goto exit;
610 }
611
612 dev_info(&i2c_client->dev,
613 "Device firmware id %d, .img firmware id %d\n",
614 deviceFirmwareID,
615 (unsigned int)imageFirmwareID);
616 if (imageFirmwareID > deviceFirmwareID) {
617 flash_area = UI_FIRMWARE;
618 goto exit;
619 }
620
621 /* device config id */
622 retval = fwu->fn_ptr->read(fwu->rmi4_data,
623 fwu->f34_fd.ctrl_base_addr,
624 config_id,
625 sizeof(config_id));
626 if (retval < 0) {
627 dev_err(&i2c_client->dev,
628 "Failed to read config ID (code %d).\n", retval);
629 flash_area = NONE;
630 goto exit;
631 }
632 deviceConfigID = extract_uint(config_id);
633
634 dev_info(&i2c_client->dev,
635 "Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
636 config_id[0], config_id[1], config_id[2], config_id[3]);
637
638 /* .img config id */
639 dev_info(&i2c_client->dev,
640 ".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
641 fwu->config_data[0],
642 fwu->config_data[1],
643 fwu->config_data[2],
644 fwu->config_data[3]);
645 imageConfigID = extract_uint(fwu->config_data);
646
647 if (imageConfigID > deviceConfigID) {
648 flash_area = CONFIG_AREA;
649 goto exit;
650 }
651
652exit:
653 kfree(imagePR);
654 if (flash_area == NONE)
655 dev_info(&i2c_client->dev,
656 "Nothing needs to be updated\n");
657 else
658 dev_info(&i2c_client->dev,
659 "Update %s block\n",
660 flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG");
661 return flash_area;
662}
663
Alexandra Chin669d27c2012-12-24 15:42:30 +0800664static int fwu_scan_pdt(void)
665{
666 int retval;
667 unsigned char ii;
668 unsigned char intr_count = 0;
669 unsigned char intr_off;
670 unsigned char intr_src;
671 unsigned short addr;
672 bool f01found = false;
673 bool f34found = false;
674 struct synaptics_rmi4_fn_desc rmi_fd;
675
676#ifdef DEBUG_FW_UPDATE
677 dev_info(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
678#endif
679
680 for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
681 retval = fwu->fn_ptr->read(fwu->rmi4_data,
682 addr,
683 (unsigned char *)&rmi_fd,
684 sizeof(rmi_fd));
685 if (retval < 0)
686 return retval;
687
688 if (rmi_fd.fn_number) {
689 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
690 "%s: Found F%02x\n",
691 __func__, rmi_fd.fn_number);
692 switch (rmi_fd.fn_number) {
693 case SYNAPTICS_RMI4_F01:
694 f01found = true;
695 fwu->f01_fd = rmi_fd;
696 fwu->addr_f01_interrupt_register =
697 fwu->f01_fd.data_base_addr + 1;
698 break;
699 case SYNAPTICS_RMI4_F34:
700 f34found = true;
701 fwu->f34_fd = rmi_fd;
702 fwu->intr_mask = 0;
703 intr_src = rmi_fd.intr_src_count;
704 intr_off = intr_count % 8;
705 for (ii = intr_off;
706 ii < ((intr_src & MASK_3BIT) +
707 intr_off);
708 ii++)
709 fwu->intr_mask |= 1 << ii;
710 break;
711 }
712 } else
713 break;
714
715 intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
716 }
717
718 if (!f01found || !f34found) {
719 dev_err(&fwu->rmi4_data->i2c_client->dev,
720 "%s: Failed to find both F01 and F34\n",
721 __func__);
722 return -EINVAL;
723 }
724
725 fwu_read_interrupt_status();
726 return 0;
727}
728
729static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt,
730 unsigned char command)
731{
732 int retval;
733 unsigned char block_offset[] = {0, 0};
734 unsigned short block_num;
Alexandra Chind5591a62013-02-07 12:59:15 -0800735 struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800736#ifdef SHOW_PROGRESS
737 unsigned int progress = (command == CMD_WRITE_CONFIG_BLOCK) ?
738 10 : 100;
739#endif
Alexandra Chind5591a62013-02-07 12:59:15 -0800740
741#ifdef DEBUG_FW_UPDATE
742 dev_info(&i2c_client->dev,
743 "%s: Start to update %s blocks\n",
744 __func__,
745 command == CMD_WRITE_CONFIG_BLOCK ?
746 "config" : "firmware");
747#endif
Alexandra Chin669d27c2012-12-24 15:42:30 +0800748 retval = fwu->fn_ptr->write(fwu->rmi4_data,
749 fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
750 block_offset,
751 sizeof(block_offset));
752 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800753 dev_err(&i2c_client->dev,
Alexandra Chin669d27c2012-12-24 15:42:30 +0800754 "%s: Failed to write to block number registers\n",
755 __func__);
756 return retval;
757 }
758
759 for (block_num = 0; block_num < block_cnt; block_num++) {
760#ifdef SHOW_PROGRESS
761 if (block_num % progress == 0)
Alexandra Chind5591a62013-02-07 12:59:15 -0800762 dev_info(&i2c_client->dev,
763 "%s: update %s %3d / %3d\n",
764 __func__,
765 command == CMD_WRITE_CONFIG_BLOCK ?
766 "config" : "firmware",
767 block_num, block_cnt);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800768#endif
769 retval = fwu->fn_ptr->write(fwu->rmi4_data,
770 fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
771 block_ptr,
772 fwu->block_size);
773 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800774 dev_err(&i2c_client->dev,
Alexandra Chin669d27c2012-12-24 15:42:30 +0800775 "%s: Failed to write block data (block %d)\n",
776 __func__, block_num);
777 return retval;
778 }
779
780 retval = fwu_write_f34_command(command);
781 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800782 dev_err(&i2c_client->dev,
Alexandra Chin669d27c2012-12-24 15:42:30 +0800783 "%s: Failed to write command for block %d\n",
784 __func__, block_num);
785 return retval;
786 }
787
788 retval = fwu_wait_for_idle(WRITE_WAIT_MS);
789 if (retval < 0) {
Alexandra Chind5591a62013-02-07 12:59:15 -0800790 dev_err(&i2c_client->dev,
791 "%s: Failed to wait for idle status (block %d)\n",
792 __func__, block_num);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800793 return retval;
794 }
795
Alexandra Chind5591a62013-02-07 12:59:15 -0800796 if (fwu->flash_control.status != 0x00) {
797 dev_err(&i2c_client->dev,
798 "%s: Flash block %d failed, status 0x%02X\n",
Alexandra Chin669d27c2012-12-24 15:42:30 +0800799 __func__, block_num, retval);
Shantanu Jain41f0d472013-01-04 12:14:37 +0530800 return retval;
Alexandra Chin669d27c2012-12-24 15:42:30 +0800801 }
Alexandra Chind5591a62013-02-07 12:59:15 -0800802
Alexandra Chin669d27c2012-12-24 15:42:30 +0800803 block_ptr += fwu->block_size;
804 }
805#ifdef SHOW_PROGRESS
Alexandra Chind5591a62013-02-07 12:59:15 -0800806 dev_info(&i2c_client->dev,
807 "%s: update %s %3d / %3d\n",
808 __func__,
809 command == CMD_WRITE_CONFIG_BLOCK ?
810 "config" : "firmware",
811 block_cnt, block_cnt);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800812#endif
813 return 0;
814}
815
816static int fwu_write_firmware(void)
817{
818 return fwu_write_blocks((unsigned char *)fwu->firmware_data,
819 fwu->fw_block_count, CMD_WRITE_FW_BLOCK);
820}
821
822static int fwu_write_configuration(void)
823{
824 return fwu_write_blocks((unsigned char *)fwu->config_data,
825 fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK);
826}
827
828static int fwu_write_bootloader_id(void)
829{
830 int retval;
831
832#ifdef DEBUG_FW_UPDATE
Alexandra Chind5591a62013-02-07 12:59:15 -0800833 dev_info(&fwu->rmi4_data->i2c_client->dev,
834 "Write bootloader ID 0x%02X 0x%02X\n",
835 fwu->bootloader_id[0],
836 fwu->bootloader_id[1]);
Alexandra Chin669d27c2012-12-24 15:42:30 +0800837#endif
838 retval = fwu->fn_ptr->write(fwu->rmi4_data,
839 fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
840 fwu->bootloader_id,
841 sizeof(fwu->bootloader_id));
842 if (retval < 0) {
843 dev_err(&fwu->rmi4_data->i2c_client->dev,
844 "%s: Failed to write bootloader ID\n",
845 __func__);
846 return retval;
847 }
848
849 return 0;
850}
851
852static int fwu_enter_flash_prog(void)
853{
854 int retval;
855 struct f01_device_status f01_device_status;
856 struct f01_device_control f01_device_control;
857
858#ifdef DEBUG_FW_UPDATE
859 dev_info(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
860#endif
861 retval = fwu_read_f01_device_status(&f01_device_status);
862 if (retval < 0)
863 return retval;
864
865 if (f01_device_status.flash_prog) {
866 dev_info(&fwu->rmi4_data->i2c_client->dev,
867 "%s: Already in flash prog mode\n",
868 __func__);
869 return 0;
870 }
871
872 retval = fwu_write_bootloader_id();
873 if (retval < 0)
874 return retval;
875
876 retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
877 if (retval < 0)
878 return retval;
879
880 retval = fwu_wait_for_idle(ENABLE_WAIT_MS);
881 if (retval < 0)
882 return retval;
883
Alexandra Chin669d27c2012-12-24 15:42:30 +0800884 retval = fwu_scan_pdt();
885 if (retval < 0)
886 return retval;
887
888 retval = fwu_read_f01_device_status(&f01_device_status);
889 if (retval < 0)
890 return retval;
891
892 if (!f01_device_status.flash_prog) {
893 dev_err(&fwu->rmi4_data->i2c_client->dev,
894 "%s: Not in flash prog mode\n",
895 __func__);
896 return -EINVAL;
897 }
898
899 retval = fwu_read_f34_queries();
900 if (retval < 0)
901 return retval;
902
903 retval = fwu->fn_ptr->read(fwu->rmi4_data,
904 fwu->f01_fd.ctrl_base_addr,
905 f01_device_control.data,
906 sizeof(f01_device_control.data));
907 if (retval < 0) {
908 dev_err(&fwu->rmi4_data->i2c_client->dev,
909 "%s: Failed to read F01 device control\n",
910 __func__);
911 return retval;
912 }
913
914 f01_device_control.nosleep = true;
915 f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
916
917 retval = fwu->fn_ptr->write(fwu->rmi4_data,
918 fwu->f01_fd.ctrl_base_addr,
919 f01_device_control.data,
920 sizeof(f01_device_control.data));
921 if (retval < 0) {
922 dev_err(&fwu->rmi4_data->i2c_client->dev,
923 "%s: Failed to write F01 device control\n",
924 __func__);
925 return retval;
926 }
927
928 return retval;
929}
930
931static int fwu_do_reflash(void)
932{
933 int retval;
934
935 retval = fwu_enter_flash_prog();
936 if (retval < 0)
937 return retval;
938
939 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
940 "%s: Entered flash prog mode\n",
941 __func__);
942
943 retval = fwu_write_bootloader_id();
944 if (retval < 0)
945 return retval;
946
947 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
948 "%s: Bootloader ID written\n",
949 __func__);
950
951 retval = fwu_write_f34_command(CMD_ERASE_ALL);
952 if (retval < 0)
953 return retval;
954
955 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
956 "%s: Erase all command written\n",
957 __func__);
958
959 retval = fwu_wait_for_idle(ERASE_WAIT_MS);
960 if (retval < 0)
961 return retval;
962
Alexandra Chind5591a62013-02-07 12:59:15 -0800963 if (fwu->flash_control.status != 0x00) {
964 dev_err(&fwu->rmi4_data->i2c_client->dev,
965 "%s: Erase all command failed, status 0x%02X\n",
966 __func__, retval);
967 return -1;
968 }
Alexandra Chin669d27c2012-12-24 15:42:30 +0800969
970 if (fwu->firmware_data) {
971 retval = fwu_write_firmware();
972 if (retval < 0)
973 return retval;
974 pr_notice("%s: Firmware programmed\n", __func__);
975 }
976
977 if (fwu->config_data) {
978 retval = fwu_write_configuration();
979 if (retval < 0)
980 return retval;
981 pr_notice("%s: Configuration programmed\n", __func__);
982 }
983
984 return retval;
985}
986
Alexandra Chin669d27c2012-12-24 15:42:30 +0800987static int fwu_do_write_config(void)
988{
989 int retval;
990
991 retval = fwu_enter_flash_prog();
992 if (retval < 0)
993 return retval;
994
995 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
996 "%s: Entered flash prog mode\n",
997 __func__);
998
999 if (fwu->config_area == PERM_CONFIG_AREA) {
1000 fwu->config_block_count = fwu->perm_config_block_count;
1001 goto write_config;
1002 }
1003
1004 retval = fwu_write_bootloader_id();
1005 if (retval < 0)
1006 return retval;
1007
1008 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1009 "%s: Bootloader ID written\n",
1010 __func__);
1011
1012 switch (fwu->config_area) {
1013 case UI_CONFIG_AREA:
1014 retval = fwu_write_f34_command(CMD_ERASE_CONFIG);
1015 break;
1016 case BL_CONFIG_AREA:
1017 retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
1018 fwu->config_block_count = fwu->bl_config_block_count;
1019 break;
1020 case DISP_CONFIG_AREA:
1021 retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
1022 fwu->config_block_count = fwu->disp_config_block_count;
1023 break;
1024 }
1025 if (retval < 0)
1026 return retval;
1027
1028 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1029 "%s: Erase command written\n",
1030 __func__);
1031
1032 retval = fwu_wait_for_idle(ERASE_WAIT_MS);
1033 if (retval < 0)
1034 return retval;
1035
1036 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1037 "%s: Idle status detected\n",
1038 __func__);
1039
1040write_config:
1041 retval = fwu_write_configuration();
1042 if (retval < 0)
1043 return retval;
1044
1045 pr_notice("%s: Config written\n", __func__);
1046
1047 return retval;
1048}
1049
1050static int fwu_start_write_config(void)
1051{
1052 int retval;
1053 struct image_header header;
1054
1055 switch (fwu->config_area) {
1056 case UI_CONFIG_AREA:
1057 break;
1058 case PERM_CONFIG_AREA:
1059 if (!fwu->flash_properties.has_perm_config)
1060 return -EINVAL;
1061 break;
1062 case BL_CONFIG_AREA:
1063 if (!fwu->flash_properties.has_bl_config)
1064 return -EINVAL;
1065 break;
1066 case DISP_CONFIG_AREA:
1067 if (!fwu->flash_properties.has_display_config)
1068 return -EINVAL;
1069 break;
1070 default:
1071 return -EINVAL;
1072 }
1073
1074 if (fwu->ext_data_source)
1075 fwu->config_data = fwu->ext_data_source;
1076 else
1077 return -EINVAL;
1078
1079 if (fwu->config_area == UI_CONFIG_AREA) {
1080 parse_header(&header, fwu->ext_data_source);
1081
1082 if (header.config_size) {
1083 fwu->config_data = fwu->ext_data_source +
1084 FW_IMAGE_OFFSET +
1085 header.image_size;
1086 } else {
1087 return -EINVAL;
1088 }
1089 }
1090
1091 pr_notice("%s: Start of write config process\n", __func__);
1092
1093 retval = fwu_do_write_config();
1094 if (retval < 0) {
1095 dev_err(&fwu->rmi4_data->i2c_client->dev,
1096 "%s: Failed to write config\n",
1097 __func__);
1098 }
1099
1100 fwu->rmi4_data->reset_device(fwu->rmi4_data);
1101
1102 pr_notice("%s: End of write config process\n", __func__);
1103
1104 return retval;
1105}
1106
1107static int fwu_do_read_config(void)
1108{
1109 int retval;
1110 unsigned char block_offset[] = {0, 0};
1111 unsigned short block_num;
1112 unsigned short block_count;
1113 unsigned short index = 0;
1114
1115 retval = fwu_enter_flash_prog();
1116 if (retval < 0)
1117 goto exit;
1118
1119 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1120 "%s: Entered flash prog mode\n",
1121 __func__);
1122
1123 switch (fwu->config_area) {
1124 case UI_CONFIG_AREA:
1125 block_count = fwu->config_block_count;
1126 break;
1127 case PERM_CONFIG_AREA:
1128 if (!fwu->flash_properties.has_perm_config) {
1129 retval = -EINVAL;
1130 goto exit;
1131 }
1132 block_count = fwu->perm_config_block_count;
1133 break;
1134 case BL_CONFIG_AREA:
1135 if (!fwu->flash_properties.has_bl_config) {
1136 retval = -EINVAL;
1137 goto exit;
1138 }
1139 block_count = fwu->bl_config_block_count;
1140 break;
1141 case DISP_CONFIG_AREA:
1142 if (!fwu->flash_properties.has_display_config) {
1143 retval = -EINVAL;
1144 goto exit;
1145 }
1146 block_count = fwu->disp_config_block_count;
1147 break;
1148 default:
1149 retval = -EINVAL;
1150 goto exit;
1151 }
1152
1153 fwu->config_size = fwu->block_size * block_count;
1154
1155 kfree(fwu->read_config_buf);
1156 fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
1157
1158 block_offset[1] |= (fwu->config_area << 5);
1159
1160 retval = fwu->fn_ptr->write(fwu->rmi4_data,
1161 fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
1162 block_offset,
1163 sizeof(block_offset));
1164 if (retval < 0) {
1165 dev_err(&fwu->rmi4_data->i2c_client->dev,
1166 "%s: Failed to write to block number registers\n",
1167 __func__);
1168 goto exit;
1169 }
1170
1171 for (block_num = 0; block_num < block_count; block_num++) {
1172 retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK);
1173 if (retval < 0) {
1174 dev_err(&fwu->rmi4_data->i2c_client->dev,
1175 "%s: Failed to write read config command\n",
1176 __func__);
1177 goto exit;
1178 }
1179
1180 retval = fwu_wait_for_idle(WRITE_WAIT_MS);
1181 if (retval < 0) {
1182 dev_err(&fwu->rmi4_data->i2c_client->dev,
1183 "%s: Failed to wait for idle status\n",
1184 __func__);
1185 goto exit;
1186 }
1187
1188 retval = fwu->fn_ptr->read(fwu->rmi4_data,
1189 fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
1190 &fwu->read_config_buf[index],
1191 fwu->block_size);
1192 if (retval < 0) {
1193 dev_err(&fwu->rmi4_data->i2c_client->dev,
1194 "%s: Failed to read block data (block %d)\n",
1195 __func__, block_num);
1196 goto exit;
1197 }
1198
1199 index += fwu->block_size;
1200 }
1201
1202exit:
1203 fwu->rmi4_data->reset_device(fwu->rmi4_data);
1204
1205 return retval;
1206}
1207
Alexandra Chind5591a62013-02-07 12:59:15 -08001208static int fwu_start_reflash(void)
1209{
1210 int retval;
1211 struct image_header header;
1212 const unsigned char *fw_image;
1213 const struct firmware *fw_entry = NULL;
1214 struct f01_device_status f01_device_status;
1215 enum flash_area flash_area;
1216
1217 pr_notice("%s: Start of reflash process\n", __func__);
1218
1219 if (fwu->ext_data_source)
1220 fw_image = fwu->ext_data_source;
1221 else {
1222 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1223 "%s: Requesting firmware image %s\n",
1224 __func__, FW_IMAGE_NAME);
1225
1226 retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
1227 &fwu->rmi4_data->i2c_client->dev);
1228 if (retval != 0) {
1229 dev_err(&fwu->rmi4_data->i2c_client->dev,
1230 "%s: Firmware image %s not available\n",
1231 __func__, FW_IMAGE_NAME);
1232 retval = -EINVAL;
1233 goto exit;
1234 }
1235
1236 dev_dbg(&fwu->rmi4_data->i2c_client->dev,
1237 "%s: Firmware image size = %d\n",
1238 __func__, fw_entry->size);
1239
1240 fw_image = fw_entry->data;
1241 }
1242
1243 parse_header(&header, fw_image);
1244
1245 if (header.image_size)
1246 fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
1247 if (header.config_size) {
1248 fwu->config_data = fw_image + FW_IMAGE_OFFSET +
1249 header.image_size;
1250 }
1251
1252 if (fwu->ext_data_source)
1253 flash_area = UI_FIRMWARE;
1254 else
1255 flash_area = fwu_go_nogo();
1256
1257 switch (flash_area) {
1258 case NONE:
1259 dev_info(&fwu->rmi4_data->i2c_client->dev,
1260 "%s: No need to do reflash.\n",
1261 __func__);
1262 goto exit;
1263 case UI_FIRMWARE:
1264 retval = fwu_do_reflash();
1265 break;
1266 case CONFIG_AREA:
1267 retval = fwu_do_write_config();
1268 break;
1269 default:
1270 dev_err(&fwu->rmi4_data->i2c_client->dev,
1271 "%s: Unknown flash area\n",
1272 __func__);
1273 goto exit;
1274 }
1275
1276 if (retval < 0) {
1277 dev_err(&fwu->rmi4_data->i2c_client->dev,
1278 "%s: Failed to do reflash\n",
1279 __func__);
1280 }
1281
1282 /* reset device */
1283 fwu_reset_device();
1284
1285 /* check device status */
1286 retval = fwu_read_f01_device_status(&f01_device_status);
1287 if (retval < 0)
1288 goto exit;
1289
1290 dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
1291 f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
1292 if (f01_device_status.flash_prog)
1293 dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
1294 f01_device_status.status_code);
1295
1296 if (f01_device_status.flash_prog) {
1297 dev_info(&fwu->rmi4_data->i2c_client->dev,
1298 "%s: Device is in flash prog mode 0x%02X\n",
1299 __func__, f01_device_status.status_code);
1300 retval = 0;
1301 goto exit;
1302 }
1303
1304 if (fw_entry)
1305 release_firmware(fw_entry);
1306
1307 pr_notice("%s: End of reflash process\n", __func__);
1308exit:
1309 return retval;
1310}
1311
Alexandra Chin669d27c2012-12-24 15:42:30 +08001312int synaptics_fw_updater(unsigned char *fw_data)
1313{
1314 int retval;
1315
1316 if (!fwu)
1317 return -ENODEV;
1318
1319 if (!fwu->initialized)
1320 return -ENODEV;
1321
1322 fwu->ext_data_source = fw_data;
1323 fwu->config_area = UI_CONFIG_AREA;
1324
1325 retval = fwu_start_reflash();
1326
1327 return retval;
1328}
1329EXPORT_SYMBOL(synaptics_fw_updater);
1330
1331static ssize_t fwu_sysfs_show_image(struct file *data_file,
1332 struct kobject *kobj, struct bin_attribute *attributes,
1333 char *buf, loff_t pos, size_t count)
1334{
1335 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1336
1337 if (count < fwu->config_size) {
1338 dev_err(&rmi4_data->i2c_client->dev,
1339 "%s: Not enough space (%d bytes) in buffer\n",
1340 __func__, count);
1341 return -EINVAL;
1342 }
1343
1344 memcpy(buf, fwu->read_config_buf, fwu->config_size);
1345
1346 return fwu->config_size;
1347}
1348
1349static ssize_t fwu_sysfs_store_image(struct file *data_file,
1350 struct kobject *kobj, struct bin_attribute *attributes,
1351 char *buf, loff_t pos, size_t count)
1352{
1353 memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]),
1354 (const void *)buf,
1355 count);
1356
1357 fwu->data_pos += count;
1358
1359 return count;
1360}
1361
1362static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
1363 struct device_attribute *attr, const char *buf, size_t count)
1364{
1365 int retval;
1366 unsigned int input;
1367 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1368
1369 if (sscanf(buf, "%u", &input) != 1) {
1370 retval = -EINVAL;
1371 goto exit;
1372 }
1373
1374 if (input != 1) {
1375 retval = -EINVAL;
1376 goto exit;
1377 }
1378
1379 retval = synaptics_fw_updater(fwu->ext_data_source);
1380 if (retval < 0) {
1381 dev_err(&rmi4_data->i2c_client->dev,
1382 "%s: Failed to do reflash\n",
1383 __func__);
1384 goto exit;
1385 }
1386
1387 retval = count;
1388
1389exit:
1390 kfree(fwu->ext_data_source);
1391 fwu->ext_data_source = NULL;
1392 return retval;
1393}
1394
1395static ssize_t fwu_sysfs_write_config_store(struct device *dev,
1396 struct device_attribute *attr, const char *buf, size_t count)
1397{
1398 int retval;
1399 unsigned int input;
1400 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1401
1402 if (sscanf(buf, "%u", &input) != 1) {
1403 retval = -EINVAL;
1404 goto exit;
1405 }
1406
1407 if (input != 1) {
1408 retval = -EINVAL;
1409 goto exit;
1410 }
1411
1412 retval = fwu_start_write_config();
1413 if (retval < 0) {
1414 dev_err(&rmi4_data->i2c_client->dev,
1415 "%s: Failed to write config\n",
1416 __func__);
1417 goto exit;
1418 }
1419
1420 retval = count;
1421
1422exit:
1423 kfree(fwu->ext_data_source);
1424 fwu->ext_data_source = NULL;
1425 return retval;
1426}
1427
1428static ssize_t fwu_sysfs_read_config_store(struct device *dev,
1429 struct device_attribute *attr, const char *buf, size_t count)
1430{
1431 int retval;
1432 unsigned int input;
1433 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1434
1435 if (sscanf(buf, "%u", &input) != 1)
1436 return -EINVAL;
1437
1438 if (input != 1)
1439 return -EINVAL;
1440
1441 retval = fwu_do_read_config();
1442 if (retval < 0) {
1443 dev_err(&rmi4_data->i2c_client->dev,
1444 "%s: Failed to read config\n",
1445 __func__);
1446 return retval;
1447 }
1448
1449 return count;
1450}
1451
1452static ssize_t fwu_sysfs_config_area_store(struct device *dev,
1453 struct device_attribute *attr, const char *buf, size_t count)
1454{
1455 int retval;
1456 unsigned long config_area;
1457
Shantanu Jain41f0d472013-01-04 12:14:37 +05301458 retval = kstrtoul(buf, 10, &config_area);
Alexandra Chin669d27c2012-12-24 15:42:30 +08001459 if (retval)
1460 return retval;
1461
1462 fwu->config_area = config_area;
1463
1464 return count;
1465}
1466
1467static ssize_t fwu_sysfs_image_size_store(struct device *dev,
1468 struct device_attribute *attr, const char *buf, size_t count)
1469{
1470 int retval;
1471 unsigned long size;
1472 struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
1473
Shantanu Jain41f0d472013-01-04 12:14:37 +05301474 retval = kstrtoul(buf, 10, &size);
Alexandra Chin669d27c2012-12-24 15:42:30 +08001475 if (retval)
1476 return retval;
1477
1478 fwu->image_size = size;
1479 fwu->data_pos = 0;
1480
1481 kfree(fwu->ext_data_source);
1482 fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
1483 if (!fwu->ext_data_source) {
1484 dev_err(&rmi4_data->i2c_client->dev,
1485 "%s: Failed to alloc mem for image data\n",
1486 __func__);
1487 return -ENOMEM;
1488 }
1489
1490 return count;
1491}
1492
1493static ssize_t fwu_sysfs_block_size_show(struct device *dev,
1494 struct device_attribute *attr, char *buf)
1495{
1496 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
1497}
1498
1499static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
1500 struct device_attribute *attr, char *buf)
1501{
1502 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count);
1503}
1504
1505static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
1506 struct device_attribute *attr, char *buf)
1507{
1508 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count);
1509}
1510
1511static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
1512 struct device_attribute *attr, char *buf)
1513{
1514 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count);
1515}
1516
1517static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
1518 struct device_attribute *attr, char *buf)
1519{
1520 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count);
1521}
1522
1523static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
1524 struct device_attribute *attr, char *buf)
1525{
1526 return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
1527}
1528
Amy Maloched25bd8c2013-01-25 12:34:31 -08001529static ssize_t fwu_sysfs_config_id_show(struct device *dev,
1530 struct device_attribute *attr, char *buf)
1531{
Amy Maloche581f7402013-02-19 16:29:37 -08001532 unsigned char config_id[4];
Amy Maloched25bd8c2013-01-25 12:34:31 -08001533 /* device config id */
1534 fwu->fn_ptr->read(fwu->rmi4_data,
1535 fwu->f34_fd.ctrl_base_addr,
1536 config_id,
1537 sizeof(config_id));
1538
1539 return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
1540 config_id[0], config_id[1], config_id[2], config_id[3]);
1541}
1542
Alexandra Chin669d27c2012-12-24 15:42:30 +08001543static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
1544 unsigned char intr_mask)
1545{
1546 if (fwu->intr_mask & intr_mask)
1547 fwu_read_f34_flash_status();
1548
1549 return;
1550}
1551
Alexandra Chind5591a62013-02-07 12:59:15 -08001552static void synaptics_rmi4_fwu_work(struct work_struct *work)
1553{
1554 fwu_start_reflash();
1555}
1556
Alexandra Chin669d27c2012-12-24 15:42:30 +08001557static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
1558{
1559 int retval;
1560 unsigned char attr_count;
1561 struct pdt_properties pdt_props;
1562
1563 fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
1564 if (!fwu) {
1565 dev_err(&rmi4_data->i2c_client->dev,
1566 "%s: Failed to alloc mem for fwu\n",
1567 __func__);
1568 goto exit;
1569 }
1570
1571 fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL);
1572 if (!fwu->fn_ptr) {
1573 dev_err(&rmi4_data->i2c_client->dev,
1574 "%s: Failed to alloc mem for fn_ptr\n",
1575 __func__);
1576 retval = -ENOMEM;
1577 goto exit_free_fwu;
1578 }
1579
1580 fwu->rmi4_data = rmi4_data;
1581 fwu->fn_ptr->read = rmi4_data->i2c_read;
1582 fwu->fn_ptr->write = rmi4_data->i2c_write;
1583 fwu->fn_ptr->enable = rmi4_data->irq_enable;
1584
1585 retval = fwu->fn_ptr->read(rmi4_data,
1586 PDT_PROPS,
1587 pdt_props.data,
1588 sizeof(pdt_props.data));
1589 if (retval < 0) {
1590 dev_dbg(&rmi4_data->i2c_client->dev,
1591 "%s: Failed to read PDT properties, assuming 0x00\n",
1592 __func__);
1593 } else if (pdt_props.has_bsr) {
1594 dev_err(&rmi4_data->i2c_client->dev,
1595 "%s: Reflash for LTS not currently supported\n",
1596 __func__);
1597 goto exit_free_mem;
1598 }
1599
1600 retval = fwu_scan_pdt();
1601 if (retval < 0)
1602 goto exit_free_mem;
1603
1604 fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0];
1605 fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1];
1606
1607 memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string,
1608 SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
1609 fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
1610
1611 dev_dbg(&rmi4_data->i2c_client->dev,
1612 "%s: F01 product info: 0x%04x 0x%04x\n",
1613 __func__, fwu->productinfo1, fwu->productinfo2);
1614 dev_dbg(&rmi4_data->i2c_client->dev,
1615 "%s: F01 product ID: %s\n",
1616 __func__, fwu->product_id);
1617
1618 retval = fwu_read_f34_queries();
1619 if (retval < 0)
1620 goto exit_free_mem;
1621
1622 fwu->initialized = true;
Alexandra Chind5591a62013-02-07 12:59:15 -08001623 fwu->force_update = FORCE_UPDATE;
Alexandra Chin669d27c2012-12-24 15:42:30 +08001624
1625 retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
1626 &dev_attr_data);
1627 if (retval < 0) {
1628 dev_err(&rmi4_data->i2c_client->dev,
1629 "%s: Failed to create sysfs bin file\n",
1630 __func__);
1631 goto exit_free_mem;
1632 }
1633
1634 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
1635 retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
1636 &attrs[attr_count].attr);
1637 if (retval < 0) {
1638 dev_err(&rmi4_data->i2c_client->dev,
1639 "%s: Failed to create sysfs attributes\n",
1640 __func__);
1641 retval = -ENODEV;
1642 goto exit_remove_attrs;
1643 }
1644 }
1645
Alexandra Chind5591a62013-02-07 12:59:15 -08001646#ifdef INSIDE_FIRMWARE_UPDATE
1647 fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
1648 INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
1649 queue_delayed_work(fwu->fwu_workqueue,
1650 &fwu->fwu_work,
1651 msecs_to_jiffies(1000));
1652#endif
Alexandra Chin669d27c2012-12-24 15:42:30 +08001653 return 0;
1654
1655exit_remove_attrs:
1656for (attr_count--; attr_count >= 0; attr_count--) {
1657 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
1658 &attrs[attr_count].attr);
1659}
1660
1661sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
1662
1663exit_free_mem:
1664 kfree(fwu->fn_ptr);
1665
1666exit_free_fwu:
1667 kfree(fwu);
1668
1669exit:
1670 return 0;
1671}
1672
1673static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
1674{
1675 unsigned char attr_count;
1676
1677 sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
1678
1679 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
1680 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
1681 &attrs[attr_count].attr);
1682 }
1683
1684 kfree(fwu->fn_ptr);
1685 kfree(fwu);
1686
1687 complete(&remove_complete);
1688
1689 return;
1690}
1691
1692static int __init rmi4_fw_update_module_init(void)
1693{
1694 synaptics_rmi4_new_function(RMI_FW_UPDATER, true,
1695 synaptics_rmi4_fwu_init,
1696 synaptics_rmi4_fwu_remove,
1697 synaptics_rmi4_fwu_attn);
1698 return 0;
1699}
1700
1701static void __exit rmi4_fw_update_module_exit(void)
1702{
1703 init_completion(&remove_complete);
1704 synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
1705 synaptics_rmi4_fwu_init,
1706 synaptics_rmi4_fwu_remove,
1707 synaptics_rmi4_fwu_attn);
1708 wait_for_completion(&remove_complete);
1709 return;
1710}
1711
1712module_init(rmi4_fw_update_module_init);
1713module_exit(rmi4_fw_update_module_exit);
1714
1715MODULE_AUTHOR("Synaptics, Inc.");
1716MODULE_DESCRIPTION("RMI4 FW Update Module");
1717MODULE_LICENSE("GPL");
Shantanu Jain41f0d472013-01-04 12:14:37 +05301718MODULE_VERSION(SYNAPTICS_RMI4_DRIVER_VERSION_STRING);