Hi all: I created a firmware extractor for these chips. Hope it is useful.
Some notes:
* Sometimes it fails in the first launch, but launching again with
exactly the same parameters works fine.
* Try to unload the touch module before running it, to avoid
interferences between both codes.
* Try first with a chunk size of 4 bytes, and change only to 2 or 1 if
it fails.
--
Nos leemos
RASTER (Linux user #228804)
[email protected] http://www.rastersoft.com
--
You received this message because you are subscribed to the Google Groups
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
/* * Copyright 2015 Raster Software Vigo * * * extract is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * extract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "extract.h" #include <errno.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <linux/i2c-dev.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <linux/input.h> #include <linux/uinput.h> #include <math.h> #ifdef USE_FB #include "linux/fb.h" #endif struct i2c_client { int adapter; }; static __inline__ void fw2buf(u8 *buf, const u32 *fw) { u32 *u32_buf = (u32 *)buf; *u32_buf = *fw; } static int gsl_ts_write(struct i2c_client *client, u8 addr, u8 *pdata, int datalen) { int ret = 0; u8 tmp_buf[128]; unsigned int bytelen; if (client==NULL) { return datalen+1; } if (datalen > 125) { printf("%s too big datalen = %d!\n", __func__, datalen); return -1; } tmp_buf[0] = addr; bytelen=1; if (datalen != 0 && pdata != NULL) { memcpy(tmp_buf+1, pdata, datalen); bytelen += datalen; } ret = write(client->adapter, tmp_buf, bytelen); return ret; } static int gsl_ts_read(struct i2c_client *client, u8 addr, u8 *pdata, unsigned int datalen) { int ret = 0; if (datalen > 126) { printf("%s too big datalen = %d!\n", __func__, datalen); return -1; } ret = write(client->adapter, &addr, 1); if (ret < 0) { printf("%s set data address fail!\n", __func__); return ret; } return read(client->adapter, pdata, datalen); } static void reset_chip(struct i2c_client *client) { u8 buf[1]; buf[0]=0x88; gsl_ts_write(client, GSL_STATUS_REG, buf, 1); usleep(10000); buf[0]=0x04; gsl_ts_write(client, 0xe4, buf, 1); usleep(10000); buf[0]=0x00; gsl_ts_write(client, 0xbc, buf, 1); usleep(10000); buf[0]=0x00; gsl_ts_write(client, 0xbd, buf, 1); usleep(10000); buf[0]=0x00; gsl_ts_write(client, 0xbe, buf, 1); usleep(10000); buf[0]=0x00; gsl_ts_write(client, 0xbf, buf, 1); usleep(10000); } static void startup_chip(struct i2c_client *client) { u8 tmp = 0x00; gsl_ts_write(client, GSL_STATUS_REG, &tmp, 1); usleep(10000); } int main(int argc, char **argv) { struct i2c_client cliente; int retval; if (argc<4) { printf("Version 1\n"); printf("Format: extract DEVICE FW_FILE BLOCK_SIZE\n\n"); printf("DEVICE: path to the I2C device where the GSLx680 chip is connected\n"); printf("FW_FILE: path to the file where to store the current firmware\n"); printf("BLOCK_SIZE: size in bytes to read in one chunk. It can be 1, 2 or 4. Try the values until there aren't read errors.\n"); printf("\nWARNING: sometimes, the first execution fails, but launching the program again, with the same parameters, works."); return 0; } char *adapter=NULL; char *firmware=NULL; int block_size=-1; char *option; int loop=1; while(loop<argc) { option=argv[loop]; loop++; if (adapter==NULL) { adapter=strdup(option); continue; } if (firmware==NULL) { firmware=strdup(option); continue; } if (block_size == -1) { block_size=atoi(option); continue; } printf("Too many parameters\n"); return -1; } printf("Connecting to device %s, storing at %s\n",adapter,firmware); cliente.adapter=open(adapter,O_RDWR); if (cliente.adapter<0) { printf("Can't open device %s\n",adapter); return -1; } if (ioctl(cliente.adapter, I2C_SLAVE, GSLX680_I2C_ADDR) < 0) { printf("Error selecting device %d\n",GSLX680_I2C_ADDR); return -2; } //reset_chip(&cliente); FILE *firmware_file = fopen(firmware,"wb"); if (firmware_file == NULL) { printf("Can't open the file %s for writting the firmware. Aborting\n",firmware); return -3; } int memory_page; int word_to_read; u8 address = 0; u8 page = 0; u8 data[4]; u32 tmp; u32 *data_bin; for(memory_page = 0; memory_page < 256; memory_page++) { printf("Accesing page %02X of 255\n",memory_page); fflush(NULL); tmp = (u32) memory_page; fw2buf(data, &tmp); retval = gsl_ts_write(&cliente,GSL_PAGE_REG,data,4); // choose memory page if (retval != 5) { printf("Error while writing to the PAGE register. Aborting.\n",retval); exit(-1); } fprintf(firmware_file,"{0x%02x,0x%x},\n",GSL_PAGE_REG,memory_page); for (address = 0; address < 128; address += 4) { data[0]=0; data[1]=0; data[2]=0; data[3]=0; if (block_size == 1) { retval = gsl_ts_read(&cliente,address,data,1); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } retval = gsl_ts_read(&cliente,address+1,data+1,1); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } retval = gsl_ts_read(&cliente,address+2,data+2,1); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } retval = gsl_ts_read(&cliente,address+3,data+3,1); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } } else if (block_size == 2) { retval = gsl_ts_read(&cliente,address,data,2); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } retval = gsl_ts_read(&cliente,address+2,data+2,2); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } } else if (block_size == 4){ retval = gsl_ts_read(&cliente,address,data,4); if (retval < 0) { printf("\nError while reading data from memory. Aborting. (Please, try again).\n"); exit(-1); } } else { printf("Chunk size incorrent. Aborting.\n"); exit(-1); } data_bin = (u32 *) data; fprintf(firmware_file,"{0x%02x,0x%08x},\n",address,*data_bin); } } fclose(firmware_file); printf("\n"); return 0; }
/* * Copyright 2015 Raster Software Vigo * * * extract is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * extract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GSLX680_EXTRACT_H_ #define _GSLX680_EXTRACT_H_ #include <unistd.h> #define GSLX680_I2C_ADDR 0x40 #define GSL_DATA_REG 0x80 #define GSL_STATUS_REG 0xE0 #define GSL_PAGE_REG 0xF0 typedef unsigned int u32; typedef unsigned short int u16; typedef unsigned char u8; typedef unsigned int bool; #define true 1 #define false 0 #endif
signature.asc
Description: OpenPGP digital signature
