├── README.md ├── documents ├── 25Q64FWIQ │ └── w25q64fw_revk_07012016_sfdp.pdf ├── AK09918 │ └── AK09918C.pdf ├── AS7024 │ ├── AS7024_DS000469_4-00.pdf │ └── AS7024_FS000207_2-00.pdf ├── BQ24050 │ └── bq24050.pdf ├── DA14580 │ ├── da14580_fs_3v4.pdf │ └── smartbond_da1458x_family_product_brief_hr.pdf ├── DPS310 │ ├── Infineon-DPS310-DS-v01_00-EN.pdf │ └── Infineon-DPS310_Pressure_Sensor-PB-v02_00-EN.pdf ├── IT7259 │ ├── IT7257_A_V0.2_20170712.pdf │ └── driver │ │ ├── Kconfig │ │ ├── Makefile │ │ ├── it7259_driver.c │ │ └── tpd_custom_it7259.h ├── LIS2DH12 │ └── lis2dh12.pdf ├── LPM013M126C │ ├── 5LL_1.28_square_BL_LPM013M126C.pdf │ └── 5LPM013M126C_specification_ver03.pdf ├── STM32L476JEY6 │ ├── DS10198.pdf │ ├── PM0214.pdf │ └── RM0351.pdf └── TPS62743 │ └── tps62743.pdf └── images ├── Amazfit_BIP_LCD_00.png ├── Amazfit_BIP_biosensors.png ├── Amazfit_BIP_bot_00.png └── Amazfit_BIP_top_00.png /README.md: -------------------------------------------------------------------------------- 1 | # Firmware 2 | [barebone firmware for the Bip](https://github.com/dslul/Amazfitbip-FreeRTOS) that uses FreeRTOS and libopencm3. 3 | 4 | To port [RebbleOS](https://github.com/ginge/FreeRTOS-Pebble), we need to switch first from the pheripheral library (that doesn't support the L4 family) they're currently using to libopencm3. 5 | 6 | # Components 7 | 8 | ## MCU - [STM32L476JEY6](https://www.st.com/en/microcontrollers-microprocessors/stm32l476je.html) 9 | 10 | Ultra-low-power with FPU ARM Cortex-M4 MCU 80 MHz with 512 Kbytes Flash, LCD, USB OTG, DFSDM. 11 | 12 | [**Datasheet**](documents/STM32L476JEY6/DS10198.pdf) 13 | 14 | [**Reference manual**](documents/STM32L476JEY6/RM0351.pdf) 15 | 16 | [**Programming manual**](documents/STM32L476JEY6/PM0214.pdf) 17 | 18 | 19 | ## LCD - [JDI LPM013M126C](https://www.j-display.com/english/product/reflective.html) 20 | 21 | 1.28” MIP Reflective 3 bit Color LTPS TFT LCD with Back Light. 22 | 23 | [**Datasheet**](documents/LPM013M126C/5LPM013M126C_specification_ver03.pdf) 24 | 25 | [**Leaflet**](documents/LPM013M126C/5LL_1.28_square_BL_LPM013M126C.pdf) 26 | 27 | 28 | ## Touchscreen - [IT7259](http://www.ite.com.tw/en/product/view?mid=112) 29 | 30 | Self-Cap Touch Controller for Wearable Device. 31 | 32 | [**Driver**](documents/IT7259/driver) 33 | 34 | Can someone who lives in China download the datasheet from csdn? https://download.csdn.net/download/raydom07/10628349 35 | 36 | Similar model: 37 | 38 | [**IT7257 datasheet**](documents/IT7259/IT7257_A_V0.2_20170712.pdf) 39 | 40 | ## Flash memory - [Winbond 25Q64FWIQ](http://www.winbond.com/hq/product/code-storage-flash-memory/serial-nor-flash/?__locale=e&partNo=W25Q64FW) 41 | 42 | 1.8V 64M-BIT serial flash memory with DUAL/QUAD SPI & QPI 43 | 44 | [**Datasheet**](documents/25Q64FWIQ/w25q64fw_revk_07012016_sfdp.pdf) 45 | 46 | 47 | ## Bluetooth - [DA14580](https://www.dialog-semiconductor.com/products/connectivity/bluetooth-low-energy/smartbond-da14580-and-da14583) 48 | 49 | Bluetooth 4.2 low energy SoC. 50 | 51 | [**Datasheet**](documents/DA14580/da14580_fs_3v4.pdf) 52 | 53 | [**Product brief**](documents/DA14580/smartbond_da1458x_family_product_brief_hr.pdf) 54 | 55 | 56 | ## GPS - [Sony CXD5603GF](https://www.sony-semicon.co.jp/products_en/gps/index.html) 57 | 58 | GPS/GNSS Receiver and Positioning Engine Solution, with GPS/GLONASS & Galileo/BeiDou support. 59 | In this configuration, there is a flash memory connected to the chip. 60 | 61 | ## Barometer - [DPS310](https://www.infineon.com/cms/en/product/sensor/barometric-pressure-sensor-for-consumer-applications/dps310/) 62 | 63 | [**Datasheet**](documents/DPS310/Infineon-DPS310-DS-v01_00-EN.pdf) 64 | 65 | [**Product brief**](documents/DPS310/Infineon-DPS310_Pressure_Sensor-PB-v02_00-EN.pdf) 66 | 67 | 68 | ## Accelerometer - [LIS2DH12](https://www.st.com/en/mems-and-sensors/lis2dh12.html) 69 | 70 | 3-axis MEMS accelerometer, ultra-low-power, ±2g/±4g/±8g/±16g full scale, high-speed I2C/SPI digital output, embedded FIFO, high-performance acceleration sensor, VFLGA package. 71 | 72 | [**Datasheet**](documents/LIS2DH12/lis2dh12.pdf) 73 | 74 | ## Compass - [AK09918](https://www.digikey.com/catalog/en/partgroup/ak09918/70323) 75 | 76 | 3-axis electronic compass IC with high sensitive Hall sensor technology. 77 | 78 | [**Datasheet**](documents/AK09918/AK09918C.pdf) 79 | 80 | 81 | ## Battery charger - [BQ24045](http://www.ti.com/product/BQ24045#) 82 | 83 | 1A, Single-Input, Single Cell Li-Ion Battery Charger for 4.35v battery. 84 | Also, BQ24040 is compatible for 4.2v battery for replacment. 85 | 86 | [**Datasheet**](http://www.ti.com/lit/ds/symlink/bq24040.pdf) 87 | 88 | 89 | ## Vital signs module - [AS7024](https://ams.com/as7024) 90 | 91 | [**Datasheet**](documents/AS7024/AS7024_DS000469_4-00.pdf) 92 | 93 | [**Product brief**](documents/AS7024/AS7024_FS000207_2-00.pdf) 94 | 95 | 96 | ## Step down voltage converter - [TPS62743](http://www.ti.com/product/TPS62743) 97 | 98 | Ultra-low-power 300mA to 400mA Step-Down Buck DCDC Converter with 360nA Iq in WCSP package. 99 | 100 | [**Datasheet**](documents/TPS62743/tps62743.pdf) 101 | 102 | 103 | 104 | # Pinouts (thanks to Viktor_7) 105 | 106 | ![top pcb](images/Amazfit_BIP_top_00.png) 107 | ![bottom pcb](images/Amazfit_BIP_bot_00.png) 108 | ![lcd](images/Amazfit_BIP_LCD_00.png) 109 | ![biosensor](images/Amazfit_BIP_biosensors.png) 110 | -------------------------------------------------------------------------------- /documents/25Q64FWIQ/w25q64fw_revk_07012016_sfdp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/25Q64FWIQ/w25q64fw_revk_07012016_sfdp.pdf -------------------------------------------------------------------------------- /documents/AK09918/AK09918C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/AK09918/AK09918C.pdf -------------------------------------------------------------------------------- /documents/AS7024/AS7024_DS000469_4-00.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/AS7024/AS7024_DS000469_4-00.pdf -------------------------------------------------------------------------------- /documents/AS7024/AS7024_FS000207_2-00.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/AS7024/AS7024_FS000207_2-00.pdf -------------------------------------------------------------------------------- /documents/BQ24050/bq24050.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/BQ24050/bq24050.pdf -------------------------------------------------------------------------------- /documents/DA14580/da14580_fs_3v4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/DA14580/da14580_fs_3v4.pdf -------------------------------------------------------------------------------- /documents/DA14580/smartbond_da1458x_family_product_brief_hr.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/DA14580/smartbond_da1458x_family_product_brief_hr.pdf -------------------------------------------------------------------------------- /documents/DPS310/Infineon-DPS310-DS-v01_00-EN.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/DPS310/Infineon-DPS310-DS-v01_00-EN.pdf -------------------------------------------------------------------------------- /documents/DPS310/Infineon-DPS310_Pressure_Sensor-PB-v02_00-EN.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/DPS310/Infineon-DPS310_Pressure_Sensor-PB-v02_00-EN.pdf -------------------------------------------------------------------------------- /documents/IT7259/IT7257_A_V0.2_20170712.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/IT7259/IT7257_A_V0.2_20170712.pdf -------------------------------------------------------------------------------- /documents/IT7259/driver/Kconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Touchscreen driver configuration 3 | # 4 | if TOUCHSCREEN_MTK_IT7259 5 | 6 | config IT7259_FIRMWARE 7 | string "IT7259 for Mediatek firmware" 8 | 9 | config IT7259_CONFIG 10 | string "IT7259 for Mediatek config" 11 | 12 | 13 | endif 14 | -------------------------------------------------------------------------------- /documents/IT7259/driver/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Linux driver folder 3 | ccflags-y += -I$(srctree)/drivers/input/touchscreen/mediatek/it7259/ 4 | ccflags-y += -I$(srctree)/drivers/input/touchscreen/mediatek/ 5 | ccflags-y += -I$(srctree)/include/linux/sched 6 | obj-y += it7259_driver.o 7 | -------------------------------------------------------------------------------- /documents/IT7259/driver/it7259_driver.c: -------------------------------------------------------------------------------- 1 | /* Copyright Statement: 2 | * 3 | * This software/firmware and related documentation ("MediaTek Software") are 4 | * protected under relevant copyright laws. The information contained herein 5 | * is confidential and proprietary to MediaTek Inc. and/or its licensors. 6 | * Without the prior written permission of MediaTek inc. and/or its licensors, 7 | * any reproduction, modification, use or disclosure of MediaTek Software, 8 | * and information contained herein, in whole or in part, shall be strictly prohibited. 9 | * 10 | * MediaTek Inc. (C) 2010. All rights reserved. 11 | * 12 | * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES 13 | * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") 14 | * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON 15 | * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. 18 | * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE 19 | * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR 20 | * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH 21 | * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES 22 | * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES 23 | * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK 24 | * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR 25 | * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND 26 | * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, 27 | * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, 28 | * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO 29 | * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 30 | * 31 | * The following software/firmware and/or related documentation ("MediaTek Software") 32 | * have been modified by MediaTek Inc. All revisions are subject to any receiver's 33 | * applicable license agreements with MediaTek Inc. 34 | */ 35 | 36 | 37 | 38 | //#include 39 | 40 | #include "tpd_custom_it7259.h" 41 | #ifndef TPD_NO_GPIO 42 | //#include "cust_gpio_usage.h" 43 | #endif 44 | #include 45 | //#include 46 | //#include 47 | //#include 48 | 49 | #include 50 | 51 | //#include "mt_boot_common.h" 52 | #include 53 | #include 54 | 55 | #include 56 | 57 | //#define __IT7259_DEBUG_A158_JFSS__ //lshun use tp for A152 58 | #define s32 int 59 | //#define I2C_SUPPORT_RS_DMA 60 | //extern kal_bool upmu_chr_det(upmu_chr_list_enum chr); // remove 61 | //taikoto 20171108 add 62 | extern struct input_dev *kpd_input_dev; 63 | //taikoto 20171108 add end 64 | unsigned int touch_irq = 0; 65 | #define ABS(x) ((x<0)?-x:x) 66 | #define TPD_OK 0 67 | #define MAX_BUFFER_SIZE 144 68 | #define CTP_NAME "IT7259" 69 | #define IOC_MAGIC 'd' 70 | #define IOCTL_SET _IOW(IOC_MAGIC, 1, struct ioctl_cmd168) 71 | #define IOCTL_GET _IOR(IOC_MAGIC, 2, struct ioctl_cmd168) 72 | #define HAS_8_BYTES_LIMIT 73 | 74 | //#define MAX_BUFFER_SIZE 1028//144 75 | #define MAX_CMD_BUFFER_SIZE 144 76 | #define MAX_FINGER_NUMBER 10 77 | #define MAX_PRESSURE 15 78 | #define DEVICE_NAME "IT7259" 79 | #define DEVICE_VENDOR 0 80 | #define DEVICE_PRODUCT 0 81 | #define DEVICE_VERSION 0 82 | #define IT7259_X_RESOLUTION 672 83 | #define IT7259_Y_RESOLUTION 672 84 | #define SCREEN_X_RESOLUTION 1440 85 | #define SCREEN_Y_RESOLUTION 768 86 | #define VERSION_ABOVE_ANDROID_20 87 | #define MAX_COUNT 3000 88 | #define COMMAND_SUCCESS 0x0000 89 | #define COMMAND_ERROR 0x0200 90 | #define ERROR_QUERY_TIME_OUT 0x0800 91 | 92 | #define QUERY_SUCCESS 0x00 93 | #define QUERY_BUSY 0x01 94 | #define QUERY_ERROR 0x02 95 | 96 | #define MAX_FILE_SIZE 0x10000 97 | #define IOC_MAGIC 'd' 98 | #define IOCTL_SET _IOW(IOC_MAGIC, 1, struct ioctl_cmd168) 99 | #define IOCTL_GET _IOR(IOC_MAGIC, 2, struct ioctl_cmd168) 100 | #define IOCTL_AP_GET 0xF0 101 | #define IOCTL_AP_SET 0xF1 102 | #define IOCTL_AP_CMD 0xF2 103 | #define IOCTL_AP_WRITE_FW 0xF3 104 | #define IOCTL_AP_COMPARE_FLASH 0xF4 105 | #define IOCTL_AP_SEND_FILE 0xF5 106 | 107 | //add by FHH for I2C DMA mode start 108 | #define MAX_I2C_NDMA_LEN 8 109 | #define MAX_I2C_DMA_LEN 240 //should less than 256 110 | static DEFINE_MUTEX(it7259_i2c_mutex); 111 | //static int tpd_i2c_dma_write(struct i2c_client *client, u32 len, u8 const *data); 112 | static int tpd_i2c_dma_read(struct i2c_client *client, u32 len, u8 const *data); 113 | //add by FHH for I2C DMA mode end 114 | 115 | extern struct tpd_device *tpd; 116 | 117 | static int tpd_flag = 0; 118 | static int tpd_halt=0; 119 | #ifdef I2C_SUPPORT_RS_DMA 120 | static u8 *I2CDMABuf_va = NULL; 121 | static u32 I2CDMABuf_pa = NULL; 122 | #endif 123 | static struct task_struct *thread = NULL; 124 | static DECLARE_WAIT_QUEUE_HEAD(waiter); 125 | #include 126 | #include 127 | #include 128 | #define MY_FILE "/data/spectrum_log.txt" 129 | 130 | enum wk_wdt_type { 131 | WK_WDT_LOC_TYPE, 132 | WK_WDT_EXT_TYPE, 133 | WK_WDT_LOC_TYPE_NOLOCK, 134 | WK_WDT_EXT_TYPE_NOLOCK, 135 | }; 136 | extern void mtk_wdt_restart(enum wk_wdt_type type); 137 | /* 138 | static void mtk_kick_wdt(void) 139 | { 140 | mtk_wdt_restart(WK_WDT_LOC_TYPE_NOLOCK); 141 | mtk_wdt_restart(WK_WDT_EXT_TYPE_NOLOCK); 142 | } 143 | */ 144 | typedef unsigned char BOOL; 145 | typedef unsigned char BYTE; 146 | 147 | typedef unsigned char uint8; 148 | typedef unsigned short WORD; 149 | typedef unsigned long int uint32; 150 | typedef unsigned int UINT; 151 | 152 | typedef signed char int8; 153 | typedef signed short int16; 154 | typedef signed long int int32; 155 | 156 | //#define MAX_BUFFER_SIZE 256 157 | 158 | #if (defined(TPD_WARP_START) && defined(TPD_WARP_END)) 159 | static int tpd_wb_start_local[TPD_WARP_CNT] = TPD_WARP_START; 160 | static int tpd_wb_end_local[TPD_WARP_CNT] = TPD_WARP_END; 161 | #endif 162 | #if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION)) 163 | static int tpd_calmat_local[8] = TPD_CALIBRATION_MATRIX; 164 | static int tpd_def_calmat_local[8] = TPD_CALIBRATION_MATRIX; 165 | #endif 166 | 167 | unsigned char APCmdBuffer[MAX_BUFFER_SIZE]; // byte 0: length byte 1~n: command byte n+1 : read length 168 | 169 | //static bool waitCommandDone(void); 170 | static void tpd_print_version(void); 171 | static void tpd_eint_interrupt_handler(void); 172 | static int touch_event_handler(void *unused); 173 | static int tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); 174 | static int tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info); 175 | static int tpd_i2c_remove(struct i2c_client *client); 176 | static int tpd_i2c_write(struct i2c_client *client, uint8_t *buf, int len); 177 | static int tpd_i2c_read(struct i2c_client *client, uint8_t *buf, int len , uint8_t addr); 178 | static int gfnIT7259_SpectrumModeTest(unsigned char ucStage); 179 | static ssize_t IT7259_SpectrumTs_show(struct device *dev, struct device_attribute *attr, char *buf); 180 | static ssize_t IT7259_SpectrumTs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); 181 | 182 | static int i2cDMAReadFromIT7259(struct i2c_client *client, uint16_t addr, uint8_t *buf, int len ); 183 | //static int i2cDMAWriteToIT7259(struct i2c_client *client, uint16_t reg, uint8_t *buf, int len); 184 | static int i2cDirectReadFromIT7259(struct i2c_client *client, uint16_t addr, uint8_t *buf, int len ); 185 | static int i2cDirectWriteToIT7259(struct i2c_client *client, uint16_t reg, uint8_t *buf, int len); 186 | 187 | extern void mt65xx_eint_unmask(unsigned int line); 188 | extern void mt65xx_eint_mask(unsigned int line); 189 | extern int mtk_wdt_enable(enum wk_wdt_en en); 190 | 191 | //lshun modify 20130615 192 | //extern void mt65xx_eint_set_hw_debounce(unsigned int eint_num, unsigned int ms); 193 | //extern unsigned int mt65xx_eint_set_sens(unsigned int eint_num, unsigned int sens); 194 | //extern void mt65xx_eint_registration(unsigned int eint_num, unsigned int is_deb_en, unsigned int pol, void (EINT_FUNC_PTR)(void), unsigned int is_auto_umask); 195 | 196 | static struct i2c_client *i2c_client = NULL; 197 | 198 | static const struct i2c_device_id tpd_i2c_id[] ={{CTP_NAME,0},{}}; // {{"mtk-tpd",0},{}}; 199 | 200 | static unsigned short force[] = {0, 0x8C, I2C_CLIENT_END,I2C_CLIENT_END}; 201 | static const unsigned short * const forces[] = { force, NULL }; 202 | //static struct i2c_client_address_data addr_data = { .forces = forces,}; 203 | 204 | //static struct i2c_board_info __initdata it7259_i2c_tpd={ I2C_BOARD_INFO(CTP_NAME, (0x8c>>1))}; 205 | static const struct of_device_id tpd_of_match[] = { 206 | {.compatible = "mediatek,cap_touch"}, 207 | {}, 208 | }; 209 | static struct i2c_driver tpd_i2c_driver = { 210 | .driver = { 211 | .name = CTP_NAME, 212 | #ifdef CONFIG_OF 213 | .of_match_table = tpd_of_match, 214 | #endif 215 | .owner = THIS_MODULE, 216 | }, 217 | .probe = tpd_i2c_probe, 218 | .remove = tpd_i2c_remove, 219 | .detect = tpd_i2c_detect, 220 | .driver.name = CTP_NAME, //"mtk-tpd", 221 | .id_table = tpd_i2c_id, 222 | // .address_list = forces, 223 | }; 224 | struct ite7259_data { 225 | rwlock_t lock; 226 | unsigned short bufferIndex; 227 | unsigned short length; 228 | unsigned short buffer[MAX_BUFFER_SIZE]; 229 | }; 230 | 231 | struct ioctl_cmd168 { 232 | unsigned short bufferIndex; 233 | unsigned short length; 234 | unsigned short buffer[MAX_BUFFER_SIZE]; 235 | }; 236 | 237 | static DEVICE_ATTR(spectrumts, S_IWUSR | S_IRUGO, IT7259_SpectrumTs_show, IT7259_SpectrumTs_store); 238 | static struct attribute *ite_attrs[] = { 239 | &dev_attr_spectrumts.attr, 240 | NULL 241 | }; 242 | 243 | static const struct attribute_group ite_attr_group = { 244 | .attrs = ite_attrs, 245 | }; 246 | 247 | //add by FHH for I2C DMA mode start 248 | /* 249 | static int tpd_i2c_dma_write(struct i2c_client *client, u32 len, u8 const *data) 250 | { 251 | u8* dmaVa = NULL; 252 | dma_addr_t dmaPa = 0; 253 | u32 written = 0 ; 254 | u32 dmaLen = MAX_I2C_DMA_LEN; 255 | u32 ext_flag; 256 | int ret; 257 | 258 | if ((len == 0) || (data == NULL) ) { 259 | return -EIO; 260 | } 261 | 262 | mutex_lock(&it7259_i2c_mutex); 263 | 264 | if (len < MAX_I2C_NDMA_LEN) { 265 | client->ext_flag &= (~I2C_DMA_FLAG); 266 | ret = i2c_master_send(client, data, len); 267 | if (len != ret) { 268 | mutex_unlock(&it7259_i2c_mutex); 269 | pr_err("%s NDMA failed: ret=%d\n", __FUNCTION__, ret); 270 | return -EIO; 271 | } 272 | } 273 | else { 274 | client->dev.coherent_dma_mask = DMA_BIT_MASK(32); 275 | dmaVa = dma_alloc_coherent(&(client->dev), MAX_I2C_DMA_LEN, &dmaPa, GFP_KERNEL); 276 | ext_flag = client->ext_flag; 277 | client->ext_flag |= (I2C_ENEXT_FLAG | I2C_DMA_FLAG); 278 | 279 | while (written < len) { 280 | if (written + MAX_I2C_DMA_LEN > len) { 281 | dmaLen = len - written; 282 | } 283 | memcpy(dmaVa, &data[written], dmaLen); 284 | ret = i2c_master_send(client, (u8*)dmaPa, dmaLen); 285 | if (dmaLen != ret) { 286 | pr_err("%s DMA failed: ret=%d\n", __FUNCTION__, ret); 287 | } 288 | written += dmaLen; 289 | } 290 | 291 | dma_free_coherent(&(client->dev), MAX_I2C_DMA_LEN, dmaVa, dmaPa); 292 | client->ext_flag = ext_flag; 293 | } 294 | 295 | mutex_unlock(&it7259_i2c_mutex); 296 | 297 | return 0; 298 | } 299 | */ 300 | static int tpd_i2c_dma_read(struct i2c_client *client, u32 len, u8 const *data) 301 | { 302 | u8* dmaVa = NULL; 303 | dma_addr_t dmaPa = 0; 304 | u32 read = 0 ; 305 | u32 dmaLen = MAX_I2C_DMA_LEN; 306 | u32 ext_flag; 307 | int ret; 308 | 309 | if ((!data) || (len == 0)) { 310 | pr_err("%s data is null\n", __FUNCTION__); 311 | return -EINVAL; 312 | } 313 | 314 | mutex_lock(&it7259_i2c_mutex); 315 | 316 | if (len <= MAX_I2C_NDMA_LEN) { 317 | client->ext_flag &= (~I2C_DMA_FLAG); 318 | ret = i2c_master_recv(client, (char*)data, len); 319 | if (len != ret) { 320 | mutex_unlock(&it7259_i2c_mutex); 321 | pr_err("%s NDMA failed: ret=%d, length=%d\n", __FUNCTION__, ret, len); 322 | return -EIO; 323 | } 324 | } else { 325 | client->dev.coherent_dma_mask = DMA_BIT_MASK(32); 326 | dmaVa = dma_alloc_coherent(&(client->dev), MAX_I2C_DMA_LEN, &dmaPa, GFP_KERNEL); 327 | ext_flag = client->ext_flag; 328 | client->ext_flag |= (I2C_ENEXT_FLAG | I2C_DMA_FLAG); 329 | 330 | while (read < len) { 331 | if (read + MAX_I2C_DMA_LEN > len) { 332 | dmaLen = len - read; 333 | } 334 | ret = i2c_master_recv(client, (u8*)dmaPa, dmaLen); 335 | if (dmaLen != ret) { 336 | pr_err("%s DMA failed: ret=%d\n", __FUNCTION__, ret); 337 | } 338 | memcpy((void*)&data[read], dmaVa, dmaLen); 339 | read += dmaLen; 340 | } 341 | 342 | dma_free_coherent(&(client->dev), MAX_I2C_DMA_LEN, dmaVa, dmaPa); 343 | client->ext_flag = ext_flag; 344 | } 345 | 346 | mutex_unlock(&it7259_i2c_mutex); 347 | 348 | return 0; 349 | } 350 | //add by FHH for I2C DMA mode end 351 | 352 | static long ite7259_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { 353 | //struct ite7259_data *dev = filp->private_data; 354 | int retval = 0; 355 | int i; 356 | //unsigned char ucQuery; 357 | unsigned char buffer[MAX_BUFFER_SIZE]; 358 | struct ioctl_cmd168 data; 359 | unsigned char datalen; 360 | unsigned char ent[] = {0x60, 0x00, 0x49, 0x54, 0x37, 0x32}; 361 | unsigned char ext[] = {0x60, 0x80, 0x49, 0x54, 0x37, 0x32}; 362 | 363 | pr_info("=ite7259_ioctl=\n"); 364 | memset(&data, 0, sizeof(struct ioctl_cmd168)); 365 | 366 | switch (cmd) { 367 | case IOCTL_SET: 368 | pr_info("=IOCTL_SET=\n"); 369 | if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) { 370 | retval = -EFAULT; 371 | goto done; 372 | } 373 | 374 | if ( copy_from_user(&data, (int __user *)arg, sizeof(struct ioctl_cmd168)) ) { 375 | retval = -EFAULT; 376 | goto done; 377 | } 378 | buffer[0] = (unsigned char) data.bufferIndex; 379 | pr_info("%.2X ", buffer[0]); 380 | for (i = 1; i < data.length + 1; i++) { 381 | buffer[i] = (unsigned char) data.buffer[i - 1]; 382 | pr_info("%.2X ", buffer[i]); 383 | } 384 | if (!memcmp(&(buffer[1]), ent, sizeof(ent))) { 385 | 386 | pr_info("Disabling IRQ.\n"); 387 | //disable_irq(gl_ts->client->irq); 388 | tpd_halt = 1; 389 | //mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); 390 | } 391 | 392 | if (!memcmp(&(buffer[1]), ext, sizeof(ext))) { 393 | 394 | pr_info("Enabling IRQ.\n"); 395 | 396 | //enable_irq(gl_ts->client->irq); 397 | tpd_halt = 0; 398 | // mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); 399 | 400 | } 401 | 402 | datalen = (unsigned char) (data.length + 1); 403 | printk("IOCTL_SET: datalen=%d.\n",datalen); 404 | retval = tpd_i2c_write(i2c_client, &buffer[0], datalen); 405 | pr_info("SET:retval=%x\n", retval); 406 | retval = 0; 407 | break; 408 | 409 | case IOCTL_GET: 410 | pr_info("=IOCTL_GET=\n"); 411 | if (!access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))) { 412 | retval = -EFAULT; 413 | goto done; 414 | } 415 | 416 | if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) { 417 | retval = -EFAULT; 418 | goto done; 419 | } 420 | 421 | if ( copy_from_user(&data, (int __user *)arg, sizeof(struct ioctl_cmd168)) ) { 422 | retval = -EFAULT; 423 | goto done; 424 | } 425 | 426 | retval = tpd_i2c_read(i2c_client, (unsigned char*) buffer, (unsigned char) data.length, (unsigned char) data.bufferIndex); 427 | 428 | pr_info("GET:retval=%x\n", retval); 429 | retval = 0; 430 | for (i = 0; i < data.length; i++) { 431 | data.buffer[i] = (unsigned short) buffer[i]; 432 | } 433 | pr_info("GET:bufferIndex=%x, dataLength=%d, buffer[0]=%x, buffer[1]=%x, buffer[2]=%x, buffer[3]=%x\n", data.bufferIndex, data.length, buffer[0], buffer[1], buffer[2], buffer[3]); 434 | 435 | if ( copy_to_user((int __user *)arg, &data, sizeof(struct ioctl_cmd168)) ) { 436 | retval = -EFAULT; 437 | goto done; 438 | } 439 | break; 440 | 441 | default: 442 | retval = -ENOTTY; 443 | break; 444 | } 445 | 446 | done: 447 | pr_info("DONE! retval=%d\n", retval); 448 | return (retval); 449 | } 450 | /************************** 451 | The output log file format should be like below 452 | 453 | Channel = 12 454 | Tx = Off 455 | Minima Frequency = 40 456 | Maxima Frequency = 110 457 | Number of Times = 10 458 | 459 | Count = 1 460 | 4099 461 | 4130 462 | 4136 463 | 4086 464 | . 465 | . 466 | Count = 2 467 | 4099 468 | 4130 469 | 4136 470 | 4086 471 | . 472 | . 473 | 474 | 475 | **************************/ 476 | 477 | int i2cReadFromIT7259(struct i2c_client *client, unsigned char writeBuffer[], unsigned short writeLength, 478 | unsigned char readDataBuffer[], unsigned short readDataLength) 479 | { 480 | #if 1 481 | int ret; 482 | 483 | if ((readDataLength > 7) ||(writeLength>7)) { 484 | return -EINVAL; 485 | } 486 | client->addr = (client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 487 | memcpy(readDataBuffer, writeBuffer, writeLength); 488 | ret = i2c_master_send(client, &readDataBuffer[0], (readDataLength << 8 | writeLength)); 489 | #else 490 | int ret; 491 | struct i2c_msg msgs[2] = { { .addr = client->addr, .flags = 0, 492 | .len = writeLength, .buf = writeBuffer }, { .addr = client->addr, .flags = 493 | I2C_M_RD, .len = readDataLength, .buf = readDataBuffer } }; 494 | printk("taikoto====in i2cReadFromIT7259 function===\n"); 495 | memset(readDataBuffer, 0xFF, readDataLength); 496 | ret = i2c_transfer(client->adapter, msgs, 2); 497 | #endif 498 | return ret; 499 | } 500 | 501 | int i2cWriteToIT7259(struct i2c_client *client, unsigned char bufferIndex, 502 | unsigned char const dataBuffer[], unsigned short dataLength) 503 | { 504 | #if 1 505 | int ret; 506 | char buffer4Write[8]; 507 | 508 | if (dataLength > 7) { 509 | return -EINVAL; 510 | } 511 | buffer4Write[0] = bufferIndex; 512 | memcpy(&(buffer4Write[1]), dataBuffer, dataLength); 513 | client->addr = client->addr & I2C_MASK_FLAG; 514 | ret = i2c_master_send(client, buffer4Write, dataLength+1); 515 | return ret; 516 | #else 517 | unsigned char buffer4Write[256]; 518 | struct i2c_msg msgs[1] = { { .addr = client->addr, .flags = 0, .len = 519 | dataLength + 1, .buf = buffer4Write } }; 520 | printk("taikoto====in i2cWriteToIT7259 function===\n"); 521 | 522 | buffer4Write[0] = bufferIndex; 523 | memcpy(&(buffer4Write[1]), dataBuffer, dataLength); 524 | return i2c_transfer(client->adapter, msgs, 1); 525 | #endif 526 | } 527 | 528 | 529 | static int i2cAdvancedReadFromIT7259(struct i2c_client *client, unsigned char writeBuffer[], unsigned short writeLength, 530 | unsigned char readDataBuffer[], unsigned short readDataLength) { 531 | #if 1 532 | int ret; 533 | 534 | if ((readDataLength > 7) ||(writeLength>7)) { 535 | return -EINVAL; 536 | } 537 | client->addr = (client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 538 | memcpy(readDataBuffer, writeBuffer, writeLength); 539 | ret = i2c_master_send(client, &readDataBuffer[0], (readDataLength << 8 | writeLength)); 540 | #else 541 | int ret; 542 | struct i2c_msg msgs[2] = { { .addr = client->addr, .flags = 0, 543 | .len = writeLength, .buf = writeBuffer }, { .addr = client->addr, .flags = 544 | I2C_M_RD, .len = readDataLength, .buf = readDataBuffer } }; 545 | printk("taikoto====in read function===\r\n"); 546 | memset(readDataBuffer, 0xFF, readDataLength); 547 | #if 0//def HAS_8_unsigned charS_LIMIT 548 | //printk("====8 byte===\r\n"); 549 | if(readDataLength >= 8) 550 | { 551 | unsigned char ucCurReadIndex = 0; 552 | unsigned char pucBuffer[128]; 553 | unsigned char pucBufferIndex =0; 554 | 555 | memset(pucBuffer, 0xFF, 128); 556 | if(bufferIndex == 0xA0) 557 | pucBufferIndex = 0x05; 558 | else if(bufferIndex == 0xE0) 559 | pucBufferIndex = 0x07; 560 | else if(bufferIndex == 0xC0) 561 | pucBufferIndex = 0x06; 562 | else 563 | pucBufferIndex = 0x05; 564 | if(IT7259ReadCommandBufferStart(pucBufferIndex)) 565 | { 566 | unsigned short ucTotalLength = dataLength; 567 | while(ucCurReadIndex< ucTotalLength) 568 | { 569 | unsigned char ucReadSize = 8; 570 | if((ucCurReadIndex + ucReadSize)>=ucTotalLength) 571 | { 572 | ret = IT7259ReadCommandBufferContinue((ucTotalLength-ucCurReadIndex),&pucBuffer[ucCurReadIndex],true); 573 | //pr_info("=read final %x--point[%x][%x][%x][%x][%x][%x][%x][%x]=\n",(ucTotalLength-ucCurReadIndex), 574 | //pucBuffer[ucCurReadIndex+0],pucBuffer[ucCurReadIndex+1],pucBuffer[ucCurReadIndex+2], 575 | //pucBuffer[ucCurReadIndex+3],pucBuffer[ucCurReadIndex+4],pucBuffer[ucCurReadIndex+5],pucBuffer[ucCurReadIndex+6],pucBuffer[ucCurReadIndex+7]); 576 | ucCurReadIndex = ucTotalLength; 577 | if(ret !=true) 578 | return false; 579 | break; 580 | } 581 | else 582 | { 583 | ret = IT7259ReadCommandBufferContinue(ucReadSize,&pucBuffer[ucCurReadIndex],false); 584 | ucCurReadIndex+=ucReadSize; 585 | if(ret !=true) 586 | return false; 587 | //pr_info("=read continue--point[%x][%x][%x][%x][%x][%x][%x][%x]=\n", 588 | //pucBuffer[0],pucBuffer[1],pucBuffer[2], 589 | //pucBuffer[3],pucBuffer[4],pucBuffer[5],pucBuffer[6],pucBuffer[7]); 590 | } 591 | } 592 | memcpy(readDataBuffer,pucBuffer,readDataLength); 593 | } 594 | else 595 | { 596 | return false; 597 | } 598 | } 599 | else 600 | { 601 | //printk("====8 byte 2===\r\n"); 602 | ret = i2c_transfer(client->adapter, msgs, 2); 603 | } 604 | 605 | #else 606 | //printk("====in i2cAdvancedReadFromIT7259 ==="); 607 | ret = i2c_transfer(client->adapter, msgs, 2); 608 | #endif 609 | #endif 610 | return ret; 611 | } 612 | /* 613 | static int i2cAdvancedWriteToIT7259(struct i2c_client *client, unsigned char bufferIndex, 614 | unsigned char const dataBuffer[], unsigned short dataLength) 615 | { 616 | //printk("====in write function==="); 617 | #if 0//def HAS_8_unsigned charS_LIMIT 618 | int ret; 619 | unsigned char buffer4Write[256]; 620 | if(dataLength>=7) 621 | { 622 | unsigned char ucCurWriteIndex = 0; 623 | unsigned char pucBufferIndex =0; 624 | 625 | memcpy(&(buffer4Write[0]), dataBuffer, dataLength); 626 | if(bufferIndex == 0x20) 627 | pucBufferIndex = 0x01; 628 | else if(bufferIndex == 0x40) 629 | pucBufferIndex = 0x02; 630 | else 631 | pucBufferIndex = 0x01; 632 | if(IT7259WriteCommandBufferStart(pucBufferIndex)) 633 | { 634 | unsigned short ucTotalLength = dataLength; 635 | while(ucCurWriteIndex< ucTotalLength) 636 | { 637 | unsigned char ucWriteSize = 5; 638 | if((ucCurWriteIndex + ucWriteSize)>=ucTotalLength) 639 | { 640 | ret = IT7259WriteCommandBufferContinue((ucTotalLength-ucCurWriteIndex),&buffer4Write[ucCurWriteIndex],true); 641 | //pr_info("=write final %x--point[%x][%x][%x][%x][%x][%x][%x][%x]=\n",(ucTotalLength-ucCurWriteIndex), 642 | //buffer4Write[ucCurWriteIndex+0],buffer4Write[ucCurWriteIndex+1],buffer4Write[ucCurWriteIndex+2], 643 | //buffer4Write[ucCurWriteIndex+3],buffer4Write[ucCurWriteIndex+4],buffer4Write[ucCurWriteIndex+5],buffer4Write[ucCurWriteIndex+6],buffer4Write[ucCurWriteIndex+7]); 644 | ucCurWriteIndex = ucTotalLength; 645 | if(ret !=true) 646 | { 647 | //printk("==============WriteCommandBufferContinue final FAIL ========================"); 648 | return false; 649 | } 650 | break; 651 | } 652 | else 653 | { 654 | ret = IT7259WriteCommandBufferContinue(ucWriteSize,&buffer4Write[ucCurWriteIndex],false); 655 | ucCurWriteIndex+=ucWriteSize; 656 | //pr_info("=write continue--point[%x][%x][%x][%x][%x][%x][%x][%x]=\n", 657 | //buffer4Write[ucCurWriteIndex],buffer4Write[ucCurWriteIndex+1],buffer4Write[ucCurWriteIndex+2], 658 | //2buffer4Write[ucCurWriteIndex+3],buffer4Write[ucCurWriteIndex+4],buffer4Write[ucCurWriteIndex+5],buffer4Write[ucCurWriteIndex+6],buffer4Write[ucCurWriteIndex+7]); 659 | if(ret !=true) 660 | { 661 | //printk("==============WriteCommandBufferContinue continue FAIL ========================"); 662 | return false; 663 | } 664 | 665 | } 666 | } 667 | } 668 | else 669 | { 670 | return false; 671 | } 672 | } 673 | else 674 | { 675 | struct i2c_msg msgs[1] = { { .addr = client->addr, .flags = 0, .len = 676 | dataLength + 1, .buf = buffer4Write } }; 677 | buffer4Write[0] = bufferIndex; 678 | memcpy(&(buffer4Write[1]), dataBuffer, dataLength); 679 | return i2c_transfer(client->adapter, msgs, 1); 680 | } 681 | 682 | #else 683 | 684 | unsigned char buffer4Write[256]; 685 | struct i2c_msg msgs[1] = { { .addr = client->addr, .flags = 0, .len = 686 | dataLength + 1, .buf = buffer4Write } }; 687 | buffer4Write[0] = bufferIndex; 688 | memcpy(&(buffer4Write[1]), dataBuffer, dataLength); 689 | return i2c_transfer(client->adapter, msgs, 1); 690 | 691 | #endif 692 | } 693 | */ 694 | bool IT7259_SendCommand( unsigned char writeBuffer[], unsigned short writeLength, 695 | unsigned char readDataBuffer[], unsigned short readDataLength) { 696 | //int i; 697 | //int tmp; 698 | unsigned char ucQuery = 0xff; 699 | unsigned char writeQueryBuffer[1]; 700 | //unsigned char buffer[128]; 701 | //unsigned char ucQueryBuffer[1]; 702 | //struct IT7259_ts_data *ts = gl_ts; 703 | int ret; 704 | int count = 0; 705 | 706 | printk("==============IT7259_SendCommand ========================\n"); 707 | 708 | writeQueryBuffer[0] = 0x80; 709 | // Identify Cap Sensor 710 | do { 711 | 712 | i2cReadFromIT7259(i2c_client, writeQueryBuffer, 1, &ucQuery, 1); 713 | printk("it7259 : count is %d....",count); 714 | count ++; 715 | } while ((ucQuery & 0x01) && (count < MAX_COUNT)); 716 | 717 | printk("it7259 : ==============step 1: %d ========================\n",count); 718 | //buffer[0] = 0x00; 719 | if(count >= MAX_COUNT) 720 | return false; 721 | 722 | ret = i2cWriteToIT7259(i2c_client, 0x20, writeBuffer, writeLength); 723 | if (ret < 0) { 724 | return false; 725 | } 726 | 727 | printk("it7259 : ==============step 2: ========================\n"); 728 | count = 0 ; 729 | ucQuery = 0xff; 730 | do { 731 | i2cReadFromIT7259(i2c_client, writeQueryBuffer, 1, &ucQuery, 1); 732 | //i2cReadFromIT7259(ts->client, 0x80, &ucQuery, 1); 733 | printk("%d....",count); 734 | count ++; 735 | } while ((ucQuery & 0x01) && (count < MAX_COUNT)); 736 | 737 | if(count >= MAX_COUNT) 738 | return false; 739 | printk("it7259 : ==============step 3: %d ========================\n",count); 740 | //memset(&buffer, 0, sizeof(buffer)); 741 | 742 | //unsigned char writeBuffer[], unsigned short writeLength, unsigned char readDataBuffer[], unsigned short readDataLength 743 | writeQueryBuffer[0] = 0xA0; 744 | ret = i2cAdvancedReadFromIT7259(i2c_client, writeQueryBuffer, 1 , readDataBuffer, readDataLength); 745 | //ret = i2cReadFromIT7259(i2c_client, writeQueryBuffer, 1, readDataBuffer, readDataLength); 746 | if (ret < 0) { 747 | return false; 748 | } 749 | 750 | pr_err("it7259 : ====Response--[%x][%x][%x][%x][%x][%x]=\n", readDataBuffer[0], readDataBuffer[1], 751 | readDataBuffer[2], readDataBuffer[3], readDataBuffer[4], readDataBuffer[5]); 752 | 753 | 754 | return true; 755 | } 756 | 757 | int gfnIT7259_SpectrumModeTest(unsigned char ucStage) 758 | { 759 | //printk("%s():\n", __func__); 760 | 761 | //unsigned char ucQuery = QUERY_BUSY; 762 | unsigned char pucCommandBuffer[1024]; 763 | unsigned int unWriteLength = 4; 764 | unsigned int unReadLength = 2; 765 | unsigned char ucTxMode = 0; //0: Tx Off, 1: Tx On 766 | unsigned short wTmp=COMMAND_ERROR; 767 | //unsigned int unCounter = 10; 768 | unsigned int unMsgLen=0; 769 | //struct IT7259_ts_data *ts = gl_ts; 770 | unsigned char msg [128]; 771 | unsigned int i ,j= 0; 772 | struct file *filp = NULL; 773 | char receivedByte[9], *p; 774 | int wAddreses; 775 | 776 | mm_segment_t old_fs; 777 | if(filp == NULL) 778 | filp = filp_open(MY_FILE, O_RDWR | O_CREAT, 0666); 779 | if (IS_ERR(filp)) { 780 | printk("it7259 : Error occured while opening file %s, exiting...\n", MY_FILE); 781 | set_fs(old_fs); 782 | if(filp != NULL) 783 | filp_close(filp, NULL); 784 | return COMMAND_ERROR; 785 | } 786 | 787 | old_fs = get_fs(); 788 | set_fs(KERNEL_DS); 789 | 790 | //if (!IS_ERR(filp)) { 791 | filp->f_op->llseek(filp,0,0); // ?\8A\E6?標移?\B0\E6?案\E9?始\EF??\8D寫?? 792 | unMsgLen = sprintf(msg,"Channel = %d\r\n", ucStage); 793 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 794 | unMsgLen = sprintf(msg,"Tx = Off\r\n"); 795 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 796 | unMsgLen = sprintf(msg,"Minima Frequency = 40\r\n"); 797 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 798 | unMsgLen = sprintf(msg,"Maxima Frequency = 110\r\n"); 799 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 800 | unMsgLen = sprintf(msg,"Number of Times = 10\r\n"); 801 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 802 | 803 | 804 | //unMsgLen = sprintf(msg,"Count = 1\r\n"); 805 | //filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 806 | 807 | //filp->f_op->write(filp, (unsigned char *)pucCommandBuffer, 1024, &filp->f_pos); 808 | //} 809 | 810 | 811 | for(i = 1;i<11;i++){ 812 | unsigned int unRetry=0; 813 | unMsgLen = sprintf(msg,"\r\nCount = %d\r\n", i); 814 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 815 | 816 | pucCommandBuffer[0] = 0x1A; 817 | pucCommandBuffer[1] = 0x01; 818 | pucCommandBuffer[2] = ucTxMode; 819 | pucCommandBuffer[3] = ucStage; 820 | //send command 821 | wTmp = IT7259_SendCommand(pucCommandBuffer,unWriteLength, pucCommandBuffer , unReadLength); //?^¶?data©??bregister?ìžm 822 | if (wTmp != true) { 823 | pr_err("msg: %s, wTmp = %d\r\n", msg, wTmp); 824 | return COMMAND_ERROR; 825 | } 826 | 827 | //read memory 828 | 829 | while(( (pucCommandBuffer[0] == 0x00)||(pucCommandBuffer[0] == 0xFF)||(pucCommandBuffer[1] == 0xFF))&&unRetry<10){ 830 | pucCommandBuffer[0] = 0x1A; 831 | pucCommandBuffer[1] = 0x01; 832 | pucCommandBuffer[2] = ucTxMode; 833 | pucCommandBuffer[3] = ucStage; 834 | wTmp = IT7259_SendCommand(pucCommandBuffer,unWriteLength, pucCommandBuffer , unReadLength); 835 | pr_info("i= %d, Retry = %d\r\n",i,unRetry); 836 | unRetry++; 837 | if (wTmp != true) 838 | return COMMAND_ERROR; 839 | } 840 | unRetry = 0; 841 | 842 | wAddreses = (int)((pucCommandBuffer[1]<<8) | pucCommandBuffer[0]); 843 | //pr_info("wAddreses : %X\r\n",wAddreses); 844 | 845 | //?¹register?ª512­?word?^š?¡C?\AC\C2?\82\AC@©w­ndirect access¡A¥?read memoryªºcommand¥hšú?^?\AC]¥i¥H¡A?ý?\ACUcommandªº?\AC芡€@?ž¥u¯??ª128bytes¡C¡A 846 | //pr_info("SpectrumMode Read Buffer Start"); 847 | wTmp = i2cDMAReadFromIT7259(i2c_client, wAddreses,pucCommandBuffer, 1024); 848 | //pr_info("SpectrumMode pucCommandBuffer\r\n"); 849 | //for(j=0;j<1024;j++) 850 | // pr_info("%X, ",pucCommandBuffer[j]); 851 | 852 | for(j=0;j<1024;j = j+2){ 853 | long intNumber; 854 | sprintf(receivedByte, "0x%02X%02X", pucCommandBuffer[j+1], pucCommandBuffer[j]); 855 | // pr_info("SpectrumMode pucCommandBuffer0: %X\r\n",pucCommandBuffer[j]); 856 | // pr_info("SpectrumMode pucCommandBuffer1: %X\r\n",pucCommandBuffer[j+1]); 857 | // pr_info("receivedByte: %s\r\n",receivedByte); 858 | intNumber = simple_strtol(receivedByte, &p, 16); 859 | unMsgLen = sprintf(msg,"%ld\r\n", intNumber); 860 | filp->f_op->write(filp, msg, unMsgLen, &filp->f_pos); 861 | } 862 | //filp->f_op->write(filp, (unsigned char *)pucCommandBuffer, 1024, &filp->f_pos); 863 | } 864 | 865 | set_fs(old_fs); 866 | if(filp != NULL) 867 | filp_close(filp, NULL); 868 | 869 | //reset FW 870 | pucCommandBuffer[0] = 0x0C; 871 | i2cWriteToIT7259(i2c_client, 0x20, pucCommandBuffer, 1); 872 | mdelay(150); 873 | 874 | 875 | if (wTmp != true) 876 | return COMMAND_ERROR; 877 | 878 | 879 | if (wTmp != COMMAND_SUCCESS) 880 | return COMMAND_ERROR; 881 | else 882 | return COMMAND_SUCCESS; 883 | 884 | 885 | 886 | } 887 | 888 | 889 | int ite7259_open(struct inode *inode, struct file *filp) { 890 | int i; 891 | struct ite7259_data *dev; 892 | 893 | pr_info("taikoto : =ite7259_open=\n"); 894 | dev = kmalloc(sizeof(struct ite7259_data), GFP_KERNEL); 895 | if (dev == NULL) { 896 | return -ENOMEM; 897 | } 898 | 899 | /* initialize members */ 900 | rwlock_init(&dev->lock); 901 | for (i = 0; i < MAX_BUFFER_SIZE; i++) { 902 | dev->buffer[i] = 0xFF; 903 | } 904 | 905 | filp->private_data = dev; 906 | 907 | return 0; /* success */ 908 | } 909 | 910 | int ite7259_close(struct inode *inode, struct file *filp) { 911 | struct ite7259_data *dev = filp->private_data; 912 | 913 | pr_info("taikoto : =ite7259_close=\n"); 914 | if (dev) { 915 | kfree(dev); 916 | } 917 | 918 | return 0; /* success */ 919 | } 920 | 921 | struct file_operations ite7259_fops = { 922 | .owner = THIS_MODULE, 923 | .open = ite7259_open, 924 | .release = ite7259_close, 925 | //.ioctl = ite7259_ioctl, 926 | .unlocked_ioctl = ite7259_ioctl, 927 | }; 928 | 929 | static struct miscdevice ctp_dev = { 930 | .minor = MISC_DYNAMIC_MINOR, 931 | .name = CTP_NAME, 932 | .fops = &ite7259_fops, 933 | }; 934 | 935 | static int tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info) { 936 | // strcpy(info->type, "mtk-tpd"); 937 | strcpy(info->type, CTP_NAME); 938 | return 0; 939 | } 940 | 941 | static int tpd_i2c_write(struct i2c_client *client, uint8_t *buf, int len) 942 | { 943 | int ret = 0; 944 | #ifdef I2C_SUPPORT_RS_DMA 945 | int i = 0; 946 | printk("taikoto : start tpd_i2c_write len=%d.\n",len); 947 | for(i = 0 ; i < len; i++){ 948 | I2CDMABuf_va[i] = buf[i]; 949 | } 950 | 951 | if(len < 8){ 952 | client->addr = client->addr & I2C_MASK_FLAG; 953 | return i2c_master_send(client, buf, len); 954 | }else{ 955 | client->addr = client->addr & I2C_MASK_FLAG | I2C_DMA_FLAG; 956 | return i2c_master_send(client, I2CDMABuf_pa, len); 957 | } 958 | #else 959 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG; 960 | ret = i2c_master_send(i2c_client, &buf[0], len); 961 | if(ret<0) 962 | printk("%s error\n",__func__); 963 | 964 | return ret; 965 | #endif 966 | return ret; 967 | } 968 | 969 | static int tpd_i2c_read(struct i2c_client *client, uint8_t *buf, int len , uint8_t addr) 970 | { 971 | int ret = 0; 972 | //printk("start tpd_i2c_read len=%d.\n",len); 973 | #ifdef I2C_SUPPORT_RS_DMA 974 | int i = 0; 975 | if(len <= 8){ 976 | buf[0] = addr; 977 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG | I2C_WR_FLAG | I2C_RS_FLAG; 978 | ret = i2c_master_send(i2c_client, &buf[0], (len << 8 | 1)); 979 | }else{ 980 | 981 | /** 982 | struct i2c_msg msg; 983 | 984 | i2c_smbus_write_byte(i2c_client, addr); 985 | msg.flags = i2c_client->flags & I2C_M_TEN; 986 | msg.timing = 100; 987 | msg.flags |= I2C_M_RD; 988 | msg.len = len; 989 | msg.ext_flag = i2c_client->ext_flag; 990 | if(len <= 8) 991 | { 992 | msg.addr = i2c_client->addr & I2C_MASK_FLAG; 993 | msg.buf = buf; 994 | ret = i2c_transfer(i2c_client->adapter, &msg, 1); 995 | return (ret == 1)? len : ret; 996 | }else{ 997 | client->addr = client->addr & I2C_MASK_FLAG | I2C_DMA_FLAG ; 998 | msg.addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_DMA_FLAG; 999 | msg.buf = I2CDMABuf_pa; 1000 | ret = i2c_transfer(i2c_client->adapter, &msg, 1); 1001 | if(ret < 0) 1002 | { 1003 | return ret; 1004 | } 1005 | for(i = 0; i < len; i++) 1006 | { 1007 | 1008 | buf[i] = I2CDMABuf_va[i]; 1009 | } 1010 | return ret; 1011 | } 1012 | */ 1013 | //i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG | I2C_WR_FLAG | I2C_RS_FLAG; 1014 | 1015 | //client->addr = client->addr & I2C_MASK_FLAG ;//| I2C_WR_FLAG | I2C_RS_FLAG; 1016 | /** 1017 | unsigned char buffer[256]; 1018 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG | I2C_WR_FLAG | I2C_RS_FLAG; 1019 | do{ 1020 | int times = len >> 3; 1021 | int last_len = len & 0x7; 1022 | int ii=0; 1023 | 1024 | for(ii=0;ii 0) 1040 | { 1041 | //ret = i2c_smbus_read_i2c_block_data(i2c_client,addr+ (ii<<2), last_len, (buf+ (ii<<2))); 1042 | // *(buf+ii<<3)=addr+ii<<3; 1043 | buf[ii<<3]=addr+ii<<3; 1044 | ret=i2c_master_send(i2c_client,&buf[ii<<3], (last_len << 8 | 1)); 1045 | printk("line 392 ret =%d",ret); 1046 | if(ret<0) 1047 | { 1048 | printk("read error 392.\n"); 1049 | } 1050 | } 1051 | }while(0); 1052 | */ 1053 | /** 1054 | I2CDMABuf_va[0] = addr; 1055 | I2CDMABuf_va[9] = 0xFF; 1056 | I2CDMABuf_va[8] = 0xFF; 1057 | 1058 | 1059 | //ret = i2c_master_recv(client, I2CDMABuf_pa, ((len+1) << 8 | 1)); 1060 | ret = i2c_master_recv(client, I2CDMABuf_pa, len); 1061 | 1062 | if(ret < 0){ 1063 | printk("%s:i2c read error.\n", __func__); 1064 | return ret; 1065 | } 1066 | 1067 | for(i = 0; i < len; i++){ 1068 | buf[i] = I2CDMABuf_va[i]; 1069 | } 1070 | */ 1071 | } 1072 | #else 1073 | buf[0] = addr; 1074 | i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1075 | ret = i2c_master_send(i2c_client, &buf[0], (len << 8 | 1)); 1076 | // i2c_smbus_read_i2c_block_data(i2c_client,addr,len,buf); 1077 | #endif 1078 | 1079 | return ret; 1080 | } 1081 | 1082 | 1083 | 1084 | static int tpd_irq_registration(void) 1085 | { 1086 | struct device_node *node = NULL; 1087 | int ret = 0; 1088 | u32 ints[2] = { 0, 0 }; 1089 | 1090 | TPD_DEBUG("Device Tree Tpd_irq_registration!\n"); 1091 | 1092 | node = of_find_matching_node(node, touch_of_match); 1093 | if (node) { 1094 | of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints)); 1095 | gpio_set_debounce(ints[0], ints[1]); 1096 | 1097 | touch_irq = irq_of_parse_and_map(node, 0); 1098 | 1099 | ret = 1100 | request_irq(touch_irq, (irq_handler_t) tpd_eint_interrupt_handler, IRQF_TRIGGER_FALLING, 1101 | "TOUCH_PANEL-eint", NULL); //IRQF_TRIGGER_FALLING IRQF_TRIGGER_RISING 1102 | if (ret > 0) { 1103 | ret = -1; 1104 | TPD_DEBUG("tpd request_irq IRQ LINE NOT AVAILABLE!.\n"); 1105 | } 1106 | 1107 | } else { 1108 | TPD_DEBUG("tpd request_irq can not find touch eint device node!.\n"); 1109 | ret = -1; 1110 | } 1111 | TPD_DEBUG("[%s]irq:%d, debounce:%d-%d:\n", __func__, touch_irq, ints[0], ints[1]); 1112 | return ret; 1113 | } 1114 | 1115 | 1116 | static ssize_t IT7259_SpectrumTs_show(struct device *dev, struct device_attribute *attr, char *buf) 1117 | { 1118 | printk("%s():\n", __func__); 1119 | 1120 | disable_irq_nosync(touch_irq); 1121 | //unsigned char APCmdBuffer[MAX_BUFFER_SIZE]; // byte 0: length byte 1~n: command byte n+1 : read length 1122 | //unsigned char readBuffer[MAX_BUFFER_SIZE]; //size should be fixed by host transfer limit 1123 | 1124 | 1125 | enable_irq(touch_irq); 1126 | return sprintf(buf, "%d", 1); // no need to show result 1127 | 1128 | } 1129 | static ssize_t IT7259_SpectrumTs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1130 | { 1131 | 1132 | int nWriteLength = 0; 1133 | //int nReadLength = 0; 1134 | //unsigned char buffer[MAX_BUFFER_SIZE]; 1135 | char cur[1000]; 1136 | //unsigned char cmd; 1137 | int i = 0 ; 1138 | int wTmp = COMMAND_ERROR; 1139 | //char *pch; 1140 | char *token; 1141 | char *tmp = cur; 1142 | char *after; 1143 | 1144 | //printk("%s():\n", __func__); 1145 | disable_irq_nosync(touch_irq); 1146 | 1147 | //unsigned char APCmdBuffer[MAX_BUFFER_SIZE]; // byte 0: length byte 1~n: command byte n+1 : read length 1148 | //unsigned char readBuffer[MAX_BUFFER_SIZE]; //size should be fixed by host transfer limit 1149 | 1150 | 1151 | 1152 | //printk("count = %d\n",count); 1153 | printk("buf:%s\n",buf); 1154 | 1155 | 1156 | 1157 | strcpy(cur, buf); 1158 | while (NULL != (token = strsep(&tmp, " "))) { 1159 | printk("token: %s\n", token); 1160 | // cmd[i] = atoi(token); 1161 | 1162 | APCmdBuffer[i] = simple_strtol(token, &after, 10); // in kernel, use simple_strtol 1163 | printk("cmd: %d\n", APCmdBuffer[i]); 1164 | i++; 1165 | } 1166 | 1167 | 1168 | //pr_info("CMD: "); 1169 | nWriteLength = (int)APCmdBuffer[0]; 1170 | pr_info("Channel: %d",nWriteLength); 1171 | 1172 | //datalen = (unsigned char) nWriteLength; 1173 | //for (i = 0; i < nWriteLength; i++) { 1174 | 1175 | // buffer[i] = APCmdBuffer[i+1]; 1176 | // pr_info(" %x ",APCmdBuffer[i+1]); 1177 | //} 1178 | 1179 | //i2cAdvancedWriteToIT7259(gl_ts->client, buffer[0], &(buffer[1]), (unsigned char)(nWriteLength - 1)); 1180 | wTmp = gfnIT7259_SpectrumModeTest(nWriteLength); 1181 | 1182 | if(wTmp != COMMAND_SUCCESS) 1183 | pr_info(" \r\nIT7259_SpectrumTs_store Fail!."); 1184 | else 1185 | pr_info(" \r\nIT7259_SpectrumTs_store Success!."); 1186 | 1187 | 1188 | enable_irq(touch_irq); 1189 | return count; 1190 | 1191 | } 1192 | 1193 | /******************************************************************************/ 1194 | static void tpd_print_version(void) 1195 | { 1196 | #ifdef I2C_SUPPORT_RS_DMA 1197 | char buffer[9]; 1198 | #else 1199 | char buffer[8]; 1200 | #endif 1201 | int ret = -1; 1202 | 1203 | do 1204 | { 1205 | buffer[0] = 0xFF; 1206 | ret = tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 1207 | } while (buffer[0] & 0x01); 1208 | 1209 | buffer[0] = 0x20; 1210 | 1211 | buffer[1] = 0x1; 1212 | 1213 | buffer[2] = 0x0; 1214 | 1215 | ret = tpd_i2c_write(i2c_client, buffer, 3); 1216 | 1217 | if (ret != 3) 1218 | { 1219 | printk("[mtk-tpd] i2c write communcate error in getting FW version : 0x%x\n", ret); 1220 | } 1221 | 1222 | msleep(10); 1223 | 1224 | do 1225 | { 1226 | buffer[0] = 0xFF; 1227 | ret = tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 1228 | } while (buffer[0] & 0x01); 1229 | 1230 | #ifdef I2C_SUPPORT_RS_DMA 1231 | ret = tpd_i2c_read(i2c_client, &buffer[0], 9, 0xA0); 1232 | 1233 | if (ret != 0x901) 1234 | { 1235 | printk("[mtk-tpd] i2c read communcate error in getting FW version : 0x%x\n", ret); 1236 | } 1237 | else 1238 | { 1239 | printk("[mtk-tpd] ITE7260 Touch Panel Firmware Version %x %x %x %x %x %x %x %x %x\n", 1240 | buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8]); 1241 | } 1242 | 1243 | #else 1244 | ret = tpd_i2c_read(i2c_client, &buffer[0], 8, 0xA0); 1245 | 1246 | if (ret != 0x801) 1247 | { 1248 | printk("[mtk-tpd] i2c read communcate error in getting FW version : 0x%x\n", ret); 1249 | } 1250 | else 1251 | { 1252 | printk("[mtk-tpd] ITE7260 Touch Panel Firmware Version %x %x %x %x %x %x %x %x\n", 1253 | buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); 1254 | } 1255 | 1256 | #endif 1257 | } 1258 | 1259 | #if 1 1260 | 1261 | /* 1262 | typedef enum wk_wdt_en 1263 | { 1264 | WK_WDT_DIS, 1265 | WK_WDT_EN, 1266 | } WD_CTL; 1267 | 1268 | #define HAS_8_BYTES_LIMIT 1269 | 1270 | extern int mtk_wdt_enable(enum wk_wdt_en en); 1271 | */ 1272 | /* 1273 | * compare fw file's version and tp version, when equal return 0, otherwise 1 1274 | */ 1275 | static int tpd_compare_fw_version(unsigned char f1, unsigned char f2, unsigned char f3, unsigned char f4) 1276 | { 1277 | #ifdef I2C_SUPPORT_RS_DMA 1278 | char buffer[9]; 1279 | #else 1280 | char buffer[8]; 1281 | #endif 1282 | int ret = -1; 1283 | 1284 | do 1285 | { 1286 | buffer[0] = 0xFF; 1287 | ret = tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 1288 | } while (buffer[0] & 0x01); 1289 | 1290 | buffer[0] = 0x20; 1291 | 1292 | buffer[1] = 0x1; 1293 | 1294 | buffer[2] = 0x0; /* 00-> firmware version, 06->config version */ 1295 | 1296 | ret = tpd_i2c_write(i2c_client, buffer, 3); 1297 | 1298 | if (ret != 3) 1299 | { 1300 | printk("[mtk-tpd] tpd_compare_fw_version: i2c write communcate error in getting FW version : 0x%x\n", ret); 1301 | } 1302 | 1303 | msleep(10); 1304 | 1305 | do 1306 | { 1307 | buffer[0] = 0xFF; 1308 | ret = tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 1309 | } while (buffer[0] & 0x01); 1310 | 1311 | #ifdef I2C_SUPPORT_RS_DMA 1312 | ret = tpd_i2c_read(i2c_client, &buffer[0], 9, 0xA0); 1313 | 1314 | if (ret != 0x901) 1315 | { 1316 | printk("[mtk-tpd] tpd_compare_fw_version: i2c read communcate error in getting FW version : 0x%x\n", ret); 1317 | } 1318 | else 1319 | { 1320 | printk("[mtk-tpd] tpd_compare_fw_version: ITE7260 Touch Panel Firmware Version %x %x %x %x %x [%x %x %x] %x, f1-f4 [%x %x %x] %x\n", 1321 | buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], f1, f2, f3, f4); 1322 | } 1323 | 1324 | #else 1325 | ret = tpd_i2c_read(i2c_client, &buffer[0], 8, 0xA0); 1326 | 1327 | if (ret != 0x801) 1328 | { 1329 | printk("[mtk-tpd] tpd_compare_fw_version: i2c read communcate error in getting FW version : 0x%x\n", ret); 1330 | } 1331 | else 1332 | { 1333 | printk("[mtk-tpd] tpd_compare_fw_version: ITE7260 Touch Panel Firmware Version %x %x %x %x %x [%x %x %x], f1-f4 [%x %x %x] %x\n", 1334 | buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], f1, f2, f3, f4); 1335 | } 1336 | 1337 | #endif 1338 | 1339 | if ((buffer[5] == f1) && (buffer[6] == f2) && (buffer[7] == f3)) /* zgdezu: only compare first three number */ 1340 | { 1341 | return 0; 1342 | } 1343 | else 1344 | { 1345 | return 1; 1346 | } 1347 | } 1348 | 1349 | /* 1350 | * compare config file's version and tp version, when equal return 0, otherwise 1 1351 | */ 1352 | static int tpd_compare_cfg_version(unsigned char c1, unsigned char c2, unsigned char c3, unsigned char c4) 1353 | { 1354 | #ifdef I2C_SUPPORT_RS_DMA 1355 | char buffer[9]; 1356 | #else 1357 | char buffer[8]; 1358 | #endif 1359 | int ret = -1; 1360 | 1361 | do 1362 | { 1363 | buffer[0] = 0xFF; 1364 | ret = tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 1365 | } while (buffer[0] & 0x01); 1366 | 1367 | buffer[0] = 0x20; 1368 | 1369 | buffer[1] = 0x1; 1370 | 1371 | buffer[2] = 0x06; /* 00-> firmware version, 06->config version */ 1372 | 1373 | ret = tpd_i2c_write(i2c_client, buffer, 3); 1374 | 1375 | if (ret != 3) 1376 | { 1377 | printk("[mtk-tpd] tpd_compare_cfg_version: i2c write communcate error in getting Config version : 0x%x\n", ret); 1378 | } 1379 | 1380 | msleep(10); 1381 | 1382 | do 1383 | { 1384 | buffer[0] = 0xFF; 1385 | ret = tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 1386 | } while (buffer[0] & 0x01); 1387 | 1388 | #ifdef I2C_SUPPORT_RS_DMA 1389 | ret = tpd_i2c_read(i2c_client, &buffer[0], 9, 0xA0); 1390 | 1391 | if (ret != 0x901) 1392 | { 1393 | printk("[mtk-tpd] tpd_compare_cfg_version: i2c read communcate error in getting Config version : 0x%x\n", ret); 1394 | } 1395 | else 1396 | { 1397 | printk("[mtk-tpd] tpd_compare_cfg_version: ITE7260 Touch Panel Config Version %x %x %x %x %x %x %x %x %x, c1-c4 [%x %x %x %x]\n", 1398 | buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], c1, c2, c3, c4); 1399 | } 1400 | 1401 | #else 1402 | ret = tpd_i2c_read(i2c_client, &buffer[0], 8, 0xA0); 1403 | 1404 | if (ret != 0x801) 1405 | { 1406 | printk("[mtk-tpd] tpd_compare_cfg_version: i2c read communcate error in getting Config version : 0x%x\n", ret); 1407 | } 1408 | else 1409 | { 1410 | printk("[mtk-tpd] tpd_compare_cfg_version: ITE7260 Touch Panel Config Version %x [%x %x %x %x] %x %x %x, c1-c4 [%x %x %x %x]\n", 1411 | buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], c1, c2, c3, c4); 1412 | } 1413 | 1414 | #endif 1415 | 1416 | if ((buffer[1] == c1) && (buffer[2] == c2) && (buffer[3] == c3) && (buffer[4] == c4)) /* zgdezu: config compare four number */ 1417 | { 1418 | return 0; 1419 | } 1420 | else 1421 | { 1422 | return 1; 1423 | } 1424 | } 1425 | 1426 | static int i2cInternalReadFromIT7259(struct i2c_client *client, uint8_t *buf, int len , uint8_t addr) 1427 | { 1428 | int ret; 1429 | int i; 1430 | uint8_t tmp[255] = {0}; 1431 | 1432 | tmp[0] = 0x70; 1433 | tmp[1] = addr; 1434 | 1435 | for( i = 0 ; i < len ; i++ ) 1436 | { 1437 | tmp[i+2] = buf[i]; 1438 | } 1439 | i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1440 | ret = i2c_master_send(i2c_client, tmp, ((len << 8) | 2)); 1441 | 1442 | for( i = 0 ; i < len ; i++ ) 1443 | { 1444 | buf[i] = tmp[i]; 1445 | } 1446 | 1447 | return ret; 1448 | } 1449 | 1450 | static int i2cInternalWriteToIT7259(struct i2c_client *client, uint8_t reg, uint8_t *buf, int len) 1451 | { 1452 | int i; 1453 | int ret; 1454 | uint8_t tmp[255] = {0}; 1455 | 1456 | tmp[0] = 0x70; 1457 | tmp[1] = reg; 1458 | for (i = 0 ; i < len ; i++) 1459 | { 1460 | tmp[i+2] = buf[i]; 1461 | } 1462 | 1463 | i2c_client->addr &= I2C_MASK_FLAG; 1464 | ret = i2c_master_send(i2c_client, tmp, len + 2); 1465 | return ret; 1466 | } 1467 | 1468 | static int i2cDMAReadFromIT7259(struct i2c_client *client, uint16_t addr, uint8_t *buf, int len ) 1469 | { 1470 | int ret; 1471 | uint8_t regAdd[4]; 1472 | 1473 | regAdd[0] = 0x90; 1474 | regAdd[1] = 0x00; 1475 | regAdd[2] = (addr &0xFF00) >> 8; 1476 | regAdd[3] = addr &0xFF; 1477 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG; 1478 | ret = i2c_master_send(i2c_client, regAdd, 4); 1479 | //i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1480 | ret = tpd_i2c_dma_read(i2c_client, len, buf); 1481 | 1482 | return ret; 1483 | } 1484 | /* 1485 | static int i2cDMAWriteToIT7259(struct i2c_client *client, uint16_t reg, uint8_t *buf, int len) 1486 | { 1487 | int nRet; 1488 | uint8_t regAdd[4]; 1489 | 1490 | regAdd[0] = 0x10; 1491 | regAdd[1] = 0x00; 1492 | regAdd[2] = (reg & 0xFF00) >> 8; 1493 | regAdd[3] = reg & 0xFF; 1494 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG; 1495 | nRet = i2c_master_send(i2c_client, regAdd, 4); 1496 | //i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1497 | nRet = tpd_i2c_dma_write(i2c_client, len, buf); 1498 | 1499 | return nRet; 1500 | } 1501 | */ 1502 | static int i2cDirectReadFromIT7259(struct i2c_client *client, uint16_t addr, uint8_t *buf, int len ) 1503 | { 1504 | #if 0 1505 | int ret; 1506 | uint8_t regAdd[4]; 1507 | 1508 | regAdd[0] = 0x90; 1509 | regAdd[1] = 0x00; 1510 | regAdd[2] = (addr &0xFF00) >> 8; 1511 | regAdd[3] = addr &0xFF; 1512 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG; 1513 | ret = i2c_master_send(i2c_client, regAdd, 4); 1514 | //i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1515 | ret = tpd_i2c_dma_read(i2c_client, len, buf); 1516 | #else 1517 | int ret; 1518 | int i; 1519 | uint8_t tmp[255] = {0}; 1520 | tmp[0] = 0x90; 1521 | tmp[1] = 0x00; 1522 | tmp[2] = (addr &0xFF00) >> 8; 1523 | tmp[3] = addr &0xFF; 1524 | 1525 | for( i = 0 ; i < len ; i++ ) 1526 | { 1527 | tmp[i+4] = buf[i]; 1528 | } 1529 | 1530 | i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1531 | ret = i2c_master_send(i2c_client, tmp, ((len << 8) | 4)); 1532 | 1533 | for (i = 0 ; i < len; i++) 1534 | { 1535 | buf[i] = tmp[i]; 1536 | } 1537 | #endif 1538 | return ret; 1539 | } 1540 | 1541 | static int i2cDirectWriteToIT7259(struct i2c_client *client, uint16_t reg, uint8_t *buf, int len) 1542 | { 1543 | #if 0 1544 | int nRet; 1545 | uint8_t regAdd[4]; 1546 | 1547 | regAdd[0] = 0x10; 1548 | regAdd[1] = 0x00; 1549 | regAdd[2] = (reg & 0xFF00) >> 8; 1550 | regAdd[3] = reg & 0xFF; 1551 | i2c_client->addr = i2c_client->addr & I2C_MASK_FLAG; 1552 | nRet = i2c_master_send(i2c_client, regAdd, 4); 1553 | //i2c_client->addr = (i2c_client->addr & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_RS_FLAG; 1554 | nRet = tpd_i2c_dma_write(i2c_client, len, buf); 1555 | #else 1556 | int i = 0; 1557 | int nRet = 0; 1558 | uint8_t tmp[255] = {0}; 1559 | 1560 | tmp[0] = 0x10; 1561 | tmp[1] = 0x00; 1562 | tmp[2] = (unsigned char)((reg &0xFF00) >> 8); 1563 | tmp[3] = (unsigned char)(reg &0xFF); 1564 | 1565 | for( i = 0 ; i < len ; i++ ) 1566 | { 1567 | tmp[i+4] = buf[i]; 1568 | } 1569 | 1570 | i2c_client->addr &= I2C_MASK_FLAG; 1571 | nRet = i2c_master_send(i2c_client, tmp, len+4); 1572 | #endif 1573 | return nRet; 1574 | } 1575 | 1576 | //20160612 Tony add 1577 | bool gfnIT7259_SwitchCPUClock(unsigned char ucMode) 1578 | { 1579 | ////// 1580 | //printk("%s(0x%02x):\n", __func__,ucMode); 1581 | 1582 | //struct IT7259_ts_data *ts = gl_ts; 1583 | unsigned char ucCommandBuffer[1]; 1584 | unsigned char ucRetCommandBuffer[1]; 1585 | 1586 | int nErrCount = 0; 1587 | int dwAddress = 0x23; 1588 | 1589 | ucCommandBuffer[0] = ucMode; 1590 | do 1591 | { 1592 | i2cInternalWriteToIT7259(i2c_client, dwAddress,ucCommandBuffer,1); 1593 | 1594 | i2cInternalReadFromIT7259(i2c_client, ucRetCommandBuffer, 1, dwAddress); 1595 | 1596 | nErrCount++; 1597 | } while (((ucRetCommandBuffer[0] & 0x0F) != ucMode) && nErrCount <= 1000); 1598 | 1599 | printk("====== gfnIT7259_SwitchCPUClock read/write OK!, nErrCount=%d ===========\n", nErrCount); 1600 | if (nErrCount>1000) 1601 | { 1602 | return false; 1603 | } 1604 | 1605 | return true; 1606 | } 1607 | 1608 | bool gfnIT7259_SPIFCRReady(void) 1609 | { 1610 | //printk("###Entry gfnIT7259_SPIFCRReady()\n"); 1611 | //struct IT7259_ts_data *ts = gl_ts; 1612 | int nReadCount=0; 1613 | unsigned char ucBuffer[2]; 1614 | 1615 | do 1616 | { 1617 | i2cDirectReadFromIT7259(i2c_client, 0xF400, ucBuffer, 2);//gfnIT7259_DirectReadMemoryRegister 1618 | } while (((ucBuffer[1]& 0x01)!=0x00) && ++nReadCount<20); //nReadCount 3000 1619 | 1620 | if (nReadCount >=20) //nReadCount 3000 1621 | { 1622 | return false; 1623 | } 1624 | 1625 | return true; 1626 | } 1627 | 1628 | int gfnIT7259_DMAModeWriteFlash(uint16_t wFlashAddress, uint16_t wSRAMAddress,unsigned int dataLength, unsigned char* pData, bool bPollingWait) 1629 | { 1630 | //printk("###Entry gfnIT7259_DMAModeWriteFlash(wFlashAddress = %04x, dataLength = %d)\n",wFlashAddress, dataLength); 1631 | //struct IT7259_ts_data *ts = gl_ts; 1632 | int nSector = 0; 1633 | int wAddress; 1634 | int wTmp; 1635 | unsigned char pucCommandBuffer[1024]; 1636 | unsigned char pucReadData[2]; 1637 | unsigned int LenOffset; 1638 | unsigned char bufTemp[4]; 1639 | int i; 1640 | unsigned int wStartAddress = wFlashAddress - (nSector*0x0400); 1641 | 1642 | //write to address 0x0000 (SRAM only 6K) 1643 | #if 0 1644 | memset(pucCommandBuffer, 0xFF, 1024); 1645 | memcpy(pucCommandBuffer, (unsigned char*)pData, dataLength * sizeof(unsigned char)); 1646 | wAddress = wSRAMAddress;//0x0000 1647 | printk("###write to address 0x0000 (wSRAMAddress = %04x, dataLength = %02x)\n",wSRAMAddress,dataLength); 1648 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,dataLength);//DirectWriteMemoryRegister 1649 | 1650 | if (wTmp <= 0) 1651 | { 1652 | //printk("###write to address 0x0000 fail!\n"); 1653 | return COMMAND_ERROR; 1654 | } 1655 | 1656 | #else 1657 | memset(bufTemp, 0xFF, 4); 1658 | 1659 | wAddress = wSRAMAddress; 1660 | 1661 | //printk("###write to address 0x0000 (wSRAMAddress = %04x, dataLength = %02x)\n",wSRAMAddress,dataLength); 1662 | 1663 | for (LenOffset=0; LenOffset < dataLength; LenOffset+=4) //for 8 byte limit 1664 | { 1665 | for (i = 0; i < 4; i++) 1666 | { 1667 | bufTemp[i] = pData[LenOffset + i]; 1668 | } 1669 | 1670 | wTmp = i2cDirectWriteToIT7259(i2c_client, wAddress, bufTemp, 4); 1671 | //mdelay(1);//for test 1672 | /*if (wTmp <= 0) 1673 | { 1674 | //printk("###write to address 0x0000 fail!\n"); 1675 | return COMMAND_ERROR; 1676 | }*/ 1677 | 1678 | wAddress = wAddress + 4; 1679 | 1680 | //printk(" ======== wAddress = %04x , LenOffset = %02x ========\n",wAddress,LenOffset); 1681 | } 1682 | 1683 | #endif 1684 | //Select Sector 1685 | memset(pucCommandBuffer, 0xFF, 1024); 1686 | 1687 | nSector = wFlashAddress/0x0400; 1688 | 1689 | pucCommandBuffer[0] = (unsigned char)(nSector & 0xFF); 1690 | 1691 | wAddress = 0xF404; 1692 | 1693 | printk("###Select Sector(nSector = %02x)\n", pucCommandBuffer[0]); 1694 | 1695 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,1);//DirectWriteMemoryRegister 1696 | //mdelay(1);//for test 1697 | printk("======= wTmp = %d =========\n",wTmp); 1698 | /*if (wTmp <= 0) 1699 | { 1700 | printk("###Select Sector fail!"); 1701 | return COMMAND_ERROR; 1702 | }*/ 1703 | 1704 | //Wait SPIFCR 1705 | //printk("###Wait SPIFCR\n"); 1706 | 1707 | if (!gfnIT7259_SPIFCRReady()) 1708 | { 1709 | return ERROR_QUERY_TIME_OUT; 1710 | } 1711 | 1712 | //Write Flash strat address 1713 | printk("###Write Flash strat address\n"); 1714 | 1715 | memset(pucCommandBuffer, 0xFF, 1024); 1716 | 1717 | wAddress = 0xF41A; 1718 | 1719 | pucCommandBuffer[0] = wStartAddress & 0x00FF; 1720 | 1721 | pucCommandBuffer[1] = (wStartAddress & 0xFF00) >> 8 ; 1722 | 1723 | printk("###Write Flash strat address(pucCommandBuffer[0] = %02x) (pucCommandBuffer[1]= %02x)\n", pucCommandBuffer[0],pucCommandBuffer[1]); 1724 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,2);//DirectWriteMemoryRegister 1725 | //mdelay(1);//for test 1726 | 1727 | /*if (wTmp <= 0) 1728 | { 1729 | printk("###Write Flash strat address fail!\n"); 1730 | return COMMAND_ERROR; 1731 | }*/ 1732 | 1733 | //Write SARM strat address 1734 | wAddress = 0xF41C; 1735 | 1736 | memset(pucCommandBuffer, 0xFF, 1024); 1737 | 1738 | pucCommandBuffer[0] = wSRAMAddress & 0xFF; 1739 | 1740 | pucCommandBuffer[1] = (wSRAMAddress & 0xFF00) >> 8 ; 1741 | 1742 | printk("###Write SARM strat address(pucCommandBuffer[0] = %02x) (pucCommandBuffer[1]= %02x)\n", pucCommandBuffer[0],pucCommandBuffer[1]); 1743 | 1744 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,2);//DirectWriteMemoryRegister 1745 | //mdelay(1);//for test 1746 | 1747 | /*if (wTmp <= 0) 1748 | { 1749 | printk("###Write SARM strat address fail!\n"); 1750 | return COMMAND_ERROR; 1751 | }*/ 1752 | 1753 | //write DMA transfer length 1754 | wAddress = 0xF41E; 1755 | 1756 | pucCommandBuffer[0] = dataLength & 0xFF; 1757 | 1758 | pucCommandBuffer[1] = (dataLength & 0xFF00) >> 8 ; 1759 | 1760 | printk("###Write DMA transfer length(pucCommandBuffer[0] = %02x) (pucCommandBuffer[1]= %02x)\n", pucCommandBuffer[0],pucCommandBuffer[1]); 1761 | 1762 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,2);//DirectWriteMemoryRegister 1763 | //mdelay(1);//for test 1764 | 1765 | /*if (wTmp <= 0) 1766 | { 1767 | //printk("###write DMA transfer length fail!\n"); 1768 | return COMMAND_ERROR; 1769 | }*/ 1770 | 1771 | //Write DMA_DIR and DMAEN 1772 | wAddress = 0xF418; 1773 | 1774 | pucCommandBuffer[0] = 0x0B; //auto erase 1775 | 1776 | pucCommandBuffer[1] = 0x00; 1777 | 1778 | printk("###Write DMA_DIR and DMAEN(pucCommandBuffer[0] = %02x) (pucCommandBuffer[1]= %02x)\n", pucCommandBuffer[0],pucCommandBuffer[1]); 1779 | 1780 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,2);//DirectWriteMemoryRegister 1781 | //mdelay(1);//for test 1782 | 1783 | /*if (wTmp <= 0) 1784 | { 1785 | printk("###Write DMA_DIR and DMAEN fail!\n"); 1786 | return COMMAND_ERROR; 1787 | }*/ 1788 | 1789 | if (bPollingWait) 1790 | { 1791 | //polling bit 0, until value of bit 0 = 0 1792 | wAddress = 0xF418; 1793 | printk("============= ivan test bPollingWait ===========\n"); 1794 | do 1795 | { 1796 | wTmp = i2cDirectReadFromIT7259(i2c_client, wAddress, pucReadData, 2);//gfnIT7259_DirectReadMemoryRegister 1797 | 1798 | /*if (wTmp <= 0) 1799 | { 1800 | break; 1801 | return COMMAND_ERROR; 1802 | }*/ 1803 | } while ((pucReadData[0] & 0x01)!= 0x00); 1804 | printk("============= ivan test bPollingWait 1===========\n"); 1805 | 1806 | //Wait SPIFCR 1807 | if (!gfnIT7259_SPIFCRReady()) 1808 | { 1809 | return ERROR_QUERY_TIME_OUT; 1810 | } 1811 | } 1812 | 1813 | return COMMAND_SUCCESS; 1814 | } 1815 | 1816 | unsigned int gfnIT7259_DirectReadFlash(uint16_t wFlashAddress, uint16_t readLength, unsigned char* pData) 1817 | { 1818 | //printk("###Entry gfnIT7259_DirectReadFlash()\n"); 1819 | //struct IT7259_ts_data *ts = gl_ts; 1820 | int nSector = 0; 1821 | unsigned char pucCommandBuffer[1024]; 1822 | int wTmp; 1823 | int wAddress; 1824 | unsigned int LenOffset; 1825 | unsigned char bufTemp[4]; 1826 | int i; 1827 | int wOffset = 0; 1828 | 1829 | nSector = wFlashAddress/0x0400; 1830 | pucCommandBuffer[0] = nSector; 1831 | 1832 | //Select Sector 1833 | wAddress = 0xF404; 1834 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,1); 1835 | 1836 | /*if (wTmp <= 0) 1837 | { 1838 | return COMMAND_ERROR; 1839 | }*/ 1840 | 1841 | //Wait SPIFCR 1842 | 1843 | if (!gfnIT7259_SPIFCRReady()) 1844 | { 1845 | return ERROR_QUERY_TIME_OUT; 1846 | } 1847 | 1848 | //Read flash 1849 | wOffset = wFlashAddress - (nSector*0x0400); 1850 | wAddress = 0x3000 + wOffset; 1851 | 1852 | #if 0 1853 | wTmp = i2cDirectReadFromIT7259(i2c_client, wAddress, pucCommandBuffer, readLength); 1854 | 1855 | if (wTmp <= 0) 1856 | { 1857 | return COMMAND_ERROR; 1858 | } 1859 | 1860 | #else 1861 | for (LenOffset = 0; LenOffset < readLength; LenOffset += 4) //for 8 byte limit 1862 | { 1863 | wTmp = i2cDirectReadFromIT7259(i2c_client, wAddress, bufTemp, 4); 1864 | 1865 | if (wTmp <= 0) 1866 | { 1867 | return COMMAND_ERROR; 1868 | } 1869 | 1870 | for (i = 0; i < 4; i++) 1871 | { 1872 | pucCommandBuffer[LenOffset + i] = bufTemp[i] ; 1873 | } 1874 | 1875 | wAddress = wAddress + 4; 1876 | 1877 | //printk(" ======== wAddress = %04x , LenOffset = %02x ========\n",wAddress,LenOffset); 1878 | } 1879 | 1880 | #endif 1881 | //Wait SPIFCR 1882 | if (!gfnIT7259_SPIFCRReady()) 1883 | { 1884 | return ERROR_QUERY_TIME_OUT; 1885 | } 1886 | 1887 | memcpy((unsigned char*)pData, pucCommandBuffer, readLength * sizeof(unsigned char)); 1888 | 1889 | return COMMAND_SUCCESS; 1890 | } 1891 | 1892 | //Tony add 1893 | static unsigned int gfnIT7259_GetFWSize(void) 1894 | { 1895 | //printk("###Entry gfnIT7259_GetFWSize()\n"); 1896 | unsigned int unRet = 0; 1897 | unsigned char arucBuffer[1024]; 1898 | uint16_t wAddress; 1899 | 1900 | wAddress = 0; 1901 | gfnIT7259_DirectReadFlash(wAddress,0x0400,arucBuffer); 1902 | 1903 | unRet = arucBuffer[0x80+12] + (arucBuffer[0x80+13] << 8); 1904 | 1905 | return unRet; 1906 | } 1907 | 1908 | int gfnIT7259_DirectEraseFlash(unsigned char ucEraseType, int wFlashAddress) 1909 | { 1910 | //printk("###Entry gfnIT7259_DirectEraseFlash()\n"); 1911 | //struct IT7259_ts_data *ts = gl_ts; 1912 | int nSector = 0; 1913 | unsigned char pucCommandBuffer[1024]; 1914 | int wTmp; 1915 | int wAddress; 1916 | nSector = wFlashAddress/0x0400; 1917 | pucCommandBuffer[0] = nSector; 1918 | 1919 | //Select Sector 1920 | wAddress = 0xF404; 1921 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,1); 1922 | 1923 | /*if (wTmp <= 0) 1924 | { 1925 | return COMMAND_ERROR; 1926 | }*/ 1927 | 1928 | //Wait SPIFCR 1929 | 1930 | if (!gfnIT7259_SPIFCRReady()) 1931 | { 1932 | return ERROR_QUERY_TIME_OUT; 1933 | } 1934 | 1935 | //Read flash 1936 | wAddress = 0xF402; 1937 | 1938 | pucCommandBuffer[0] = ucEraseType; 1939 | 1940 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,1); 1941 | 1942 | //Wait SPIFCR 1943 | if (!gfnIT7259_SPIFCRReady()) 1944 | { 1945 | return ERROR_QUERY_TIME_OUT; 1946 | } 1947 | 1948 | return COMMAND_SUCCESS; 1949 | } 1950 | 1951 | int gfnIT7259_DirectWriteFlash(int wFlashAddress, unsigned int wWriteLength, unsigned char* pData) 1952 | { 1953 | //printk("###Entry gfnIT7259_DirectWriteFlash().......wWriteLength = %d\n",wWriteLength); 1954 | //struct IT7259_ts_data *ts = gl_ts; 1955 | int nSector = 0; 1956 | unsigned char pucCommandBuffer[1024]; 1957 | int wTmp; 1958 | int wAddress; 1959 | int wOffset = 0; 1960 | 1961 | nSector = wFlashAddress/0x0400; 1962 | pucCommandBuffer[0] = nSector; 1963 | 1964 | //Select Sector 1965 | wAddress = 0xF404; 1966 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,1); 1967 | 1968 | /*if (wTmp <= 0) 1969 | { 1970 | return COMMAND_ERROR; 1971 | }*/ 1972 | 1973 | //Wait SPIFCR 1974 | 1975 | if (!gfnIT7259_SPIFCRReady()) 1976 | { 1977 | return ERROR_QUERY_TIME_OUT; 1978 | } 1979 | 1980 | //write flash 1981 | wOffset = wFlashAddress - (nSector*0x0400); 1982 | wAddress = 0x3000 + wOffset; 1983 | 1984 | memcpy(pucCommandBuffer, (unsigned char*)pData, wWriteLength * sizeof(unsigned char)); 1985 | 1986 | //wTmp = gfnIT7259_DirectWriteMemoryRegister(0x01,wAddress,0x0000,wWriteLength, pucCommandBuffer); 1987 | wTmp = i2cDirectWriteToIT7259(i2c_client,wAddress,pucCommandBuffer,wWriteLength); 1988 | 1989 | /*if (wTmp <= 0) 1990 | { 1991 | return COMMAND_ERROR; 1992 | }*/ 1993 | 1994 | //Wait SPIFCR 1995 | 1996 | if (!gfnIT7259_SPIFCRReady()) 1997 | { 1998 | return ERROR_QUERY_TIME_OUT; 1999 | } 2000 | 2001 | return COMMAND_SUCCESS; 2002 | } 2003 | 2004 | //Tony add for IT 7259 2005 | bool gfnIT7259_FirmwareDownload(unsigned int unFirmwareLength, unsigned char arucFW[], unsigned int unConfigLength, unsigned char arucConfig[]) 2006 | { 2007 | // printk("%s\n", __func__); 2008 | /* 2009 | if ((unFirmwareLength == 0 ) && (unConfigLength == 0 )) 2010 | { 2011 | printk("XXX %s, %d\n", __FUNCTION__, __LINE__); 2012 | return false; 2013 | } 2014 | else 2015 | { 2016 | printk("###001 Entry gfnIT7259_FirmwareDownload()\n"); 2017 | } 2018 | */ 2019 | int dwAddress; 2020 | 2021 | unsigned char RetDATABuffer[10]; 2022 | 2023 | unsigned char DATABuffer[10]; 2024 | 2025 | int nSector = 0; 2026 | 2027 | unsigned int nFillSize = 0; 2028 | 2029 | int wTmp; 2030 | 2031 | unsigned int unTmp = gfnIT7259_GetFWSize(); 2032 | 2033 | // unsigned int nConfigSize = unConfigLength; 2034 | 2035 | 2036 | //3.7 get address for writing config (in flash) 2037 | //check whether fw and config are in the same sector or not 2038 | //set flash size 2039 | unsigned long dwFlashSize = 0x10000; 2040 | 2041 | unsigned int nEndFwSector = (unTmp-1) / 1024; 2042 | 2043 | unsigned int nStartCFGSector = 62 - (unConfigLength-1)/1024; 2044 | 2045 | unsigned char putFWBuffer[1024]; 2046 | 2047 | unsigned int nRemainderFwSize = 0; 2048 | int nConfigCount = 0; 2049 | unsigned int i = 0; 2050 | 2051 | if ((unFirmwareLength == 0 ) && (unConfigLength == 0 )) 2052 | { 2053 | printk("XXX %s, %d\n", __FUNCTION__, __LINE__); 2054 | return false; 2055 | } 2056 | 2057 | //trun off CPU data clock 2058 | if (!gfnIT7259_SwitchCPUClock(0x01)) 2059 | { 2060 | printk("###002 gfnIT7259_SwitchCPUClock(0x01) fail!\n"); 2061 | return false; 2062 | } 2063 | 2064 | printk("###002 gfnIT7259_SwitchCPUClock(0x01) OK!\n"); 2065 | 2066 | //Wait SPIFCR 2067 | printk("###003 Wait SPIFCR\n"); 2068 | dwAddress = 0xF400; 2069 | 2070 | do 2071 | { 2072 | i2cDirectReadFromIT7259(i2c_client,dwAddress,RetDATABuffer,2); 2073 | } while ((RetDATABuffer[1] & 0x01) != 0x00); 2074 | 2075 | printk("###003 End SPIFCR\n"); 2076 | 2077 | //Erase signature 2078 | printk("###004 Erase signature\n"); 2079 | 2080 | dwAddress = 0xF404; 2081 | 2082 | DATABuffer[0] = 0x3F; 2083 | 2084 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,1); 2085 | 2086 | dwAddress = 0xF402; 2087 | 2088 | DATABuffer[0] = 0xD7; 2089 | 2090 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,1); 2091 | 2092 | //Wait SPIFCR 2093 | printk("###005 Wait SPIFCR\n"); 2094 | 2095 | dwAddress = 0xF400; 2096 | 2097 | do 2098 | { 2099 | i2cDirectReadFromIT7259(i2c_client,dwAddress,RetDATABuffer,2); 2100 | } while ((RetDATABuffer[1] & 0x01) != 0x00); 2101 | 2102 | printk("###005 End SPIFCR\n"); 2103 | 2104 | //Download FW 2105 | printk("###006 Download FW\n"); 2106 | 2107 | for (i = 0 ; i < unFirmwareLength ; i+=0x0400) //0x0400 2108 | { 2109 | if ((unFirmwareLength - i) >= 0x0400)//0x0400 2110 | nFillSize = 0x0400;//0x0400 2111 | else 2112 | nFillSize = unFirmwareLength - i ; 2113 | 2114 | wTmp = gfnIT7259_DMAModeWriteFlash(i,0x0000,nFillSize,arucFW+i,true); 2115 | 2116 | //mdelay(1);//for test 2117 | 2118 | if (wTmp != COMMAND_SUCCESS) 2119 | { 2120 | //Write Firmware Flash error 2121 | printk("###DMA ModeWrite Firmware Flash error(FlashAddress:%04x)\n",i); 2122 | return false; 2123 | } 2124 | } 2125 | 2126 | //3. Fw CRC Check 2127 | 2128 | //check FW CRC 2129 | printk("###007 check FW CRC\n"); 2130 | 2131 | //write start address 2132 | printk("###007 write start address\n"); 2133 | 2134 | dwAddress = 0xF40A; 2135 | 2136 | DATABuffer[0] = 0x00; 2137 | 2138 | DATABuffer[1] = 0x00; 2139 | 2140 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,2); 2141 | 2142 | //write end address 2143 | printk("###007 write end address\n"); 2144 | 2145 | dwAddress = 0xF40C; 2146 | 2147 | DATABuffer[0] = (unFirmwareLength-3) & 0x00ff ; 2148 | 2149 | DATABuffer[1] = ((unFirmwareLength-3) & 0xff00)>>8; 2150 | 2151 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,2); 2152 | 2153 | //write CRCCR 2154 | printk("###007 write CRCCR\n"); 2155 | 2156 | dwAddress = 0xF408; 2157 | 2158 | DATABuffer[0] = 0x01 ; 2159 | 2160 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,1); 2161 | 2162 | //wait CRCCR 2163 | printk("###007 wait CRCCR\n"); 2164 | 2165 | dwAddress = 0xF408; 2166 | 2167 | do 2168 | { 2169 | i2cDirectReadFromIT7259(i2c_client,dwAddress,RetDATABuffer,2); 2170 | } while ((RetDATABuffer[0] & 0x01) != 0x00); 2171 | 2172 | //read CRC 2173 | printk("###007 read CRC\n"); 2174 | 2175 | dwAddress = 0xF40E; 2176 | 2177 | i2cDirectReadFromIT7259(i2c_client,dwAddress,RetDATABuffer,2); 2178 | printk("###007 read CRC RetDATABuffer[0] = 0x%x, RetDATABuffer[1] = 0x%x\n",RetDATABuffer[0],RetDATABuffer[1]); 2179 | 2180 | //compare FW CRC 2181 | printk("###008 compare FW CRC\n"); 2182 | 2183 | if (RetDATABuffer[0]!= arucFW[unFirmwareLength - 2] || RetDATABuffer[1]!= arucFW[unFirmwareLength - 1]) 2184 | { 2185 | printk("###008 FW CRC check fail\n"); 2186 | printk("RetDATABuffer[0]:%02x,RetDATABuffer[1]:%02x,FW[Length-2]:%02x,FW[Length-1]:%02x\n",RetDATABuffer[0], RetDATABuffer[1], arucFW[unFirmwareLength - 2], arucFW[unFirmwareLength - 1]); 2187 | return false;//FW CRC check fail 2188 | } 2189 | 2190 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2191 | 2192 | //download config 2193 | printk("###009 start to download config\n"); 2194 | 2195 | printk("###009-1 start to download config\n"); 2196 | 2197 | if (nEndFwSector == nStartCFGSector) 2198 | { 2199 | int wAddress = nEndFwSector*0x0400; 2200 | nRemainderFwSize = unTmp - nEndFwSector*1024; 2201 | gfnIT7259_DirectReadFlash(wAddress,nRemainderFwSize,putFWBuffer); 2202 | } 2203 | 2204 | //get config start address 2205 | wTmp = dwFlashSize -1024 - unConfigLength; 2206 | 2207 | printk("###010 get config start address(%04x)\n",wTmp); 2208 | 2209 | for (i = wTmp ; i<(dwFlashSize -1024) ; i+=0x0400) 2210 | { 2211 | int nSize = 0; 2212 | int wConfigAddress = 0; 2213 | 2214 | nSector = i/0x0400; 2215 | 2216 | if ((nRemainderFwSize!=0) && (nSector == nStartCFGSector)) 2217 | { 2218 | int wRemainderFWAddress = nStartCFGSector*0x0400; 2219 | nFillSize = nRemainderFwSize; 2220 | gfnIT7259_DMAModeWriteFlash(wRemainderFWAddress,0x0000,nFillSize,putFWBuffer,true); 2221 | } 2222 | 2223 | //write config 2224 | nSize = (unConfigLength - (62-nSector)*1024); 2225 | 2226 | if (nSize >=1024) 2227 | { 2228 | wConfigAddress = nSector * 0x0400; 2229 | nFillSize = 1024; 2230 | } 2231 | else 2232 | { 2233 | wConfigAddress = i; 2234 | nFillSize = nSize; 2235 | } 2236 | 2237 | wTmp = gfnIT7259_DMAModeWriteFlash(wConfigAddress ,0x0000, nFillSize, arucConfig + nConfigCount , true); 2238 | 2239 | if (wTmp != COMMAND_SUCCESS) 2240 | return false; 2241 | 2242 | nConfigCount += nFillSize; 2243 | } 2244 | 2245 | //Config CRC Check 2246 | printk("###011 Config CRC Check\n"); 2247 | 2248 | //write start address 2249 | printk("###011 write Config start address\n"); 2250 | 2251 | dwAddress = 0xF40A; 2252 | 2253 | DATABuffer[0] = (0x10000 - unConfigLength -1024) & 0x00ff; 2254 | 2255 | DATABuffer[1] = ((0x10000- unConfigLength -1024) & 0xff00)>>8; 2256 | 2257 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,2); 2258 | 2259 | //write end address 2260 | printk("###011 write Config end address\n"); 2261 | 2262 | dwAddress = 0xF40C; 2263 | 2264 | DATABuffer[0] = (0x10000 -1024 -3)& 0x00ff; 2265 | 2266 | DATABuffer[1] = ((0x10000-1024 -3) & 0xff00)>>8; 2267 | 2268 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,2); 2269 | 2270 | //write CRCCR 2271 | printk("###011 write CRCCR\n"); 2272 | 2273 | dwAddress = 0xF408; 2274 | 2275 | DATABuffer[0] = 0x01 ; 2276 | 2277 | i2cDirectWriteToIT7259(i2c_client,dwAddress,DATABuffer,1); 2278 | 2279 | //wait CRCCR 2280 | printk("###011 wait CRCCR\n"); 2281 | 2282 | dwAddress = 0xF408; 2283 | 2284 | do 2285 | { 2286 | i2cDirectReadFromIT7259(i2c_client,dwAddress,RetDATABuffer,2); 2287 | } while ((RetDATABuffer[0] & 0x01) != 0x00); 2288 | 2289 | //read CRC 2290 | printk("###011 read CRC\n"); 2291 | 2292 | dwAddress = 0xF40E; 2293 | 2294 | i2cDirectReadFromIT7259(i2c_client,dwAddress,RetDATABuffer,2); 2295 | 2296 | //compare Config CRC 2297 | printk("###011 compare Config CRC\n"); 2298 | 2299 | if (RetDATABuffer[0]!= arucConfig[unConfigLength - 2] || RetDATABuffer[1]!= arucConfig[unConfigLength - 1]) 2300 | { 2301 | printk("###011 config CRC Check Error\n"); 2302 | printk("RetDATABuffer[0]:%02x,RetDATABuffer[1]:%02x,CFG[Length-2]:%02x,CFG[Length-1]:%02x\n",RetDATABuffer[0], RetDATABuffer[1], arucConfig[unConfigLength - 2], arucConfig[unConfigLength - 1]); 2303 | return false;//config CRC Check Error 2304 | } 2305 | 2306 | DATABuffer[0] = 0x59; 2307 | 2308 | DATABuffer[1] = 0x72; 2309 | 2310 | gfnIT7259_DirectEraseFlash(0xD7,(dwFlashSize -1024)); 2311 | gfnIT7259_DirectWriteFlash((dwFlashSize -1024),2,DATABuffer); 2312 | 2313 | DATABuffer[0] = 0x00; 2314 | DATABuffer[1] = 0x00; 2315 | i2cDirectReadFromIT7259(i2c_client,dwAddress,DATABuffer,2); 2316 | 2317 | //trun on CPU data clock 2318 | printk("###012 trun on CPU data clock\n"); 2319 | 2320 | if (!gfnIT7259_SwitchCPUClock(0x04)) 2321 | { 2322 | printk("###012 trun on CPU data clock fail\n"); 2323 | return false; 2324 | } 2325 | 2326 | printk("###gfnIT7259_FirmwareDownload() end.\n"); 2327 | 2328 | return true; 2329 | } 2330 | 2331 | static int Upgrade_FW_CFG(void) 2332 | { 2333 | // printk("Execute Upgrade_FW_CFG().\n"); 2334 | unsigned int fw_size = 0; 2335 | unsigned int config_size = 0; 2336 | return 0; 2337 | #if 0 2338 | 2339 | struct file *fw_fd = NULL; 2340 | 2341 | struct file *config_fd = NULL; 2342 | mm_segment_t fs; 2343 | 2344 | printk("Upgrade_FW_CFG 1.\n"); 2345 | // unsigned char *fw_buf = kzalloc(0x10000, GFP_KERNEL); 2346 | // unsigned char *config_buf = kzalloc(0x500, GFP_KERNEL); 2347 | 2348 | if (fw_buf == NULL || config_buf == NULL) 2349 | { 2350 | printk("kzalloc failed.\n"); 2351 | return 1; 2352 | } 2353 | 2354 | printk("Upgrade_FW_CFG 2.\n"); 2355 | 2356 | fs = get_fs(); 2357 | 2358 | printk("Upgrade_FW_CFG 3.\n"); 2359 | set_fs(get_ds()); 2360 | 2361 | printk("Upgrade_FW_CFG 4.\n"); 2362 | 2363 | //load fw file 2364 | fw_fd = filp_open("/system/etc/firmware/firmware_ver_1.16.0.0_2016_09_13_14_54_33.bin", O_RDONLY, 0); 2365 | 2366 | if (fw_fd <= 0) 2367 | { 2368 | //if(IS_ERR(fw_fd)) { 2369 | printk("open /system/etc/firmware/firmware_ver_1.16.0.0_2016_09_13_14_54_33.bin failed, fw_fd=%02X.\n", (unsigned int)fw_fd); 2370 | return 1; 2371 | } 2372 | 2373 | printk("Upgrade_FW_CFG 5.\n"); 2374 | 2375 | fw_size = fw_fd->f_op->read(fw_fd, fw_buf, 0x10000, &fw_fd->f_pos); 2376 | //printk("fw_ver : %d,%d,%d,%d\n",fw_buf[8], fw_buf[9], fw_buf[10], fw_buf[11]); 2377 | //printk("--------------------- fw_size = %x\n", fw_size); 2378 | 2379 | printk("Upgrade_FW_CFG 6.\n"); 2380 | //load config file 2381 | config_fd = filp_open("/system/etc/firmware/config_ver1.1.5.5.bin", O_RDONLY, 0); 2382 | 2383 | if (config_fd <= 0) 2384 | { 2385 | //if(IS_ERR(config_fd)) { 2386 | printk("open /system/etc/firmware/config_ver1.1.5.5.bin failed, config_fd=%02X.\n", (unsigned int)config_fd); 2387 | return 1; 2388 | } 2389 | 2390 | printk("Upgrade_FW_CFG 7.\n"); 2391 | 2392 | config_size = config_fd->f_op->read(config_fd, config_buf, 0x500, &config_fd->f_pos); 2393 | //printk("cfg_ver : %d,%d,%d,%d\n",config_buf[config_size-8], config_buf[config_size-7], config_buf[config_size-6], config_buf[config_size-5]); 2394 | //printk("--------------------- config_size = %x\n", config_size); 2395 | //end 2396 | 2397 | set_fs(fs); 2398 | filp_close(fw_fd,NULL); 2399 | filp_close(config_fd,NULL); 2400 | #else 2401 | fw_size = sizeof(fw_buf1); 2402 | config_size = sizeof(config_buf1); 2403 | #endif 2404 | 2405 | if (0 == tpd_compare_fw_version(fw_buf1[136], fw_buf1[137], fw_buf1[138], fw_buf1[139])) 2406 | { 2407 | printk("IT7259 Firmware equal.\n"); 2408 | 2409 | if (0 == tpd_compare_cfg_version(config_buf1[config_size-8], config_buf1[config_size-7], config_buf1[config_size-6], config_buf1[config_size-5])) 2410 | { 2411 | printk("IT7259 Config equal.\n"); 2412 | return 1; 2413 | } 2414 | } 2415 | 2416 | printk("IT7259 mtk_wdt_enable(WK_WDT_DIS).\n"); 2417 | 2418 | #if 1 2419 | mtk_wdt_enable(WK_WDT_DIS); 2420 | 2421 | printk("IT7259 gfnIT7259_FirmwareDownload().\n"); 2422 | 2423 | if (gfnIT7259_FirmwareDownload(fw_size, fw_buf1, config_size, config_buf1) == false) 2424 | { 2425 | //fail 2426 | printk("Execute gfnIT7259_FirmwareDownload fail.\n"); 2427 | mtk_wdt_enable(WK_WDT_EN); 2428 | return 1; 2429 | } 2430 | else 2431 | { 2432 | //success 2433 | printk("Execute gfnIT7259_FirmwareDownload success.\n"); 2434 | mtk_wdt_enable(WK_WDT_EN); 2435 | return 0; 2436 | } 2437 | 2438 | #else 2439 | return 1; 2440 | 2441 | #endif 2442 | } 2443 | 2444 | #endif 2445 | 2446 | /*******************************************************************************/ 2447 | 2448 | 2449 | static int tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) 2450 | { 2451 | int err = 0;//, ret = -1 2452 | unsigned char Wrbuf[2] = { 0x20, 0x07 }; 2453 | // unsigned char Rdbuffer[10]; 2454 | int retval; 2455 | #ifdef I2C_SUPPORT_RS_DMA 2456 | char buffer[9]; 2457 | #else 2458 | char buffer[8]; 2459 | #endif 2460 | char i=0; 2461 | // char buffer1[14]; 2462 | 2463 | i2c_client = client; 2464 | // add i2c_device_id 2465 | if (i2c_client->addr != 0x46) 2466 | { 2467 | i2c_client->addr = 0x46; 2468 | } 2469 | 2470 | printk(" taikoto : MediaTek it7259 touch panel i2c probe:%s\n", id->name); 2471 | #if 0 //by FHH 2472 | //#else 2473 | mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO); 2474 | mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT); 2475 | mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO); 2476 | msleep(150); 2477 | mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE); 2478 | hwPowerOn(MT65XX_POWER_LDO_VGP2, VOL_2800, "TP"); 2479 | // Power Output Low 2480 | //mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_GPIO); 2481 | // mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE); 2482 | //mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN,GPIO_PULL_UP); 2483 | // mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_OUT); 2484 | // mt_set_gpio_out(GPIO_CTP_EINT_PIN, GPIO_OUT_ZERO); 2485 | // Interrupt Output Low 2486 | msleep(100); 2487 | // Power Output High 2488 | mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT); 2489 | mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_IN); 2490 | mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE); 2491 | mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN, GPIO_PULL_UP); 2492 | // Interrupt Input High 2493 | msleep(50); 2494 | #endif 2495 | retval = regulator_enable(tpd->reg); 2496 | if (retval != 0) 2497 | TPD_DMESG("Failed to enable reg-vgp6: %d\n", retval); 2498 | tpd_gpio_output(GTP_RST_PORT, 1); //ugrec_tky gpio_direction_output(tpd_rst_gpio_number, 0); 2499 | msleep(100); 2500 | tpd_gpio_output(GTP_RST_PORT, 0); //ugrec_tky gpio_direction_output(tpd_rst_gpio_number, 1); 2501 | msleep(200); 2502 | tpd_gpio_output(GTP_RST_PORT, 1); //ugrec_tky gpio_direction_output(tpd_rst_gpio_number, 0); 2503 | #ifdef I2C_SUPPORT_RS_DMA 2504 | I2CDMABuf_va = (u8 *)dma_alloc_coherent(NULL, 4096, &I2CDMABuf_pa, GFP_KERNEL); 2505 | if(!I2CDMABuf_va) 2506 | { 2507 | printk("it7259 Allocate Touch DMA I2C Buffer failed!\n"); 2508 | return -1; 2509 | } 2510 | #endif 2511 | //ret = sysfs_create_group(&(client->dev.kobj), &it7259_attr_group); 2512 | err = sysfs_create_group(&client->dev.kobj, &ite_attr_group); 2513 | 2514 | msleep(100); 2515 | //kthread_run(upgrade_thread_kthread, NULL, "upgrade_thread_kthread"); 2516 | /*mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_SENSITIVE); 2517 | mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN); 2518 | mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_TOUCH_PANEL_POLARITY, tpd_eint_interrupt_handler, 1); 2519 | mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);*/ 2520 | tpd_irq_registration();//ugrec_tky 2521 | //enable_irq(touch_irq); 2522 | printk("taikoto : MediaTek it7259 touch panel i2c probe success\n"); 2523 | msleep(100); 2524 | 2525 | tpd_print_version(); //read firmware version 2526 | 2527 | tpd_i2c_write(i2c_client, Wrbuf, 2); // Clean Queue {0x20, 0x07} 2528 | do{ 2529 | i++; 2530 | tpd_i2c_read(i2c_client, buffer, 1, 0x80); 2531 | if(i>100) 2532 | { 2533 | i = 0; 2534 | break; 2535 | } 2536 | }while( buffer[0] & 0x01 ); 2537 | 2538 | if(tpd_i2c_read(i2c_client, buffer, 2, 0xA0) < 0) 2539 | { 2540 | TPD_DMESG("taikoto : it7259 I2C transfer error, line: %d\n", __LINE__); 2541 | // return -1; //ysong 2542 | } 2543 | 2544 | thread = kthread_run(touch_event_handler, 0, CTP_NAME); 2545 | if (IS_ERR(thread)) { 2546 | err = PTR_ERR(thread); 2547 | printk(CTP_NAME " taikoto : it7259 failed to create kernel thread: %d\n", err); 2548 | } 2549 | 2550 | tpd_load_status = 1; 2551 | printk("DDD_____ 0xA0 : %X, %X\n", buffer[0], buffer[1]); // add FAE End 2552 | 2553 | #if 1 2554 | tpd_halt = 1; 2555 | Upgrade_FW_CFG(); 2556 | msleep(100); 2557 | tpd_halt = 0; 2558 | #endif 2559 | 2560 | return 0; 2561 | } 2562 | 2563 | void tpd_eint_interrupt_handler(void) 2564 | { 2565 | TPD_DEBUG_PRINT_INT; 2566 | tpd_flag = 1; 2567 | printk("tp_int\n"); 2568 | wake_up_interruptible(&waiter); 2569 | } 2570 | 2571 | static int tpd_i2c_remove(struct i2c_client *client) 2572 | { 2573 | #ifdef I2C_SUPPORT_RS_DMA 2574 | if( I2CDMABuf_va ){ 2575 | dma_free_coherent(NULL, 4096, I2CDMABuf_va, I2CDMABuf_pa); 2576 | I2CDMABuf_va = NULL; 2577 | I2CDMABuf_pa = 0; 2578 | } 2579 | #endif 2580 | return 0; 2581 | } 2582 | 2583 | void tpd_down(int raw_x, int raw_y, int x, int y, int p) { 2584 | 2585 | input_report_abs(tpd->dev, ABS_PRESSURE, 128); 2586 | input_report_key(tpd->dev, BTN_TOUCH, 1); 2587 | input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 128); 2588 | input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 128); 2589 | input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); 2590 | input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); 2591 | 2592 | input_mt_sync(tpd->dev); 2593 | //printk("D[%4d %4d %4d]\n", x, y, p); //by FHH 2594 | TPD_EM_PRINT(raw_x, raw_y, x, y, p, 1); 2595 | } 2596 | 2597 | void tpd_up(int raw_x, int raw_y, int x, int y, int p) { 2598 | 2599 | input_report_abs(tpd->dev, ABS_PRESSURE, 0); 2600 | input_report_key(tpd->dev, BTN_TOUCH, 0); 2601 | input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 0); 2602 | input_report_abs(tpd->dev, ABS_MT_WIDTH_MAJOR, 0); 2603 | input_report_abs(tpd->dev, ABS_MT_POSITION_X, x); 2604 | input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); 2605 | input_mt_sync(tpd->dev); 2606 | //printk("U[%4d %4d %4d]\n", x, y, 0); //by FHH 2607 | TPD_EM_PRINT(raw_x, raw_y, x, y, p, 0); 2608 | } 2609 | 2610 | static int x[2] = { (int) -1, (int) -1 }; 2611 | static int y[2] = { (int) -1, (int) -1 }; 2612 | static bool finger[2] = { 0, 0 }; 2613 | static bool flag = 0; 2614 | 2615 | static int touch_event_handler( void *unused ) 2616 | { 2617 | struct sched_param param = { .sched_priority = RTPM_PRIO_TPD }; 2618 | unsigned char pucPoint[14]; 2619 | //unsigned char key_temp=0; 2620 | #ifndef I2C_SUPPORT_RS_DMA 2621 | unsigned char cPoint[8]; 2622 | unsigned char ePoint[6]; 2623 | unsigned char Rd_P_buf[3] = { 0x20,0x18, 0x07 }; 2624 | unsigned char Rd_keep[4] = { 0x20,0x19, 0x00, 0x06 }; 2625 | unsigned char Rd_final[4] = { 0x20,0x19, 0x01, 0x08 }; 2626 | unsigned char buffer[1]; 2627 | #endif 2628 | int ret = 0; 2629 | int xraw, yraw; 2630 | int i = 0; 2631 | 2632 | sched_setscheduler(current, SCHED_RR, ¶m); 2633 | do{ 2634 | set_current_state(TASK_INTERRUPTIBLE); 2635 | while (tpd_halt) {tpd_flag = 0; msleep(20);} 2636 | wait_event_interruptible(waiter, tpd_flag != 0); 2637 | tpd_flag = 0; 2638 | TPD_DEBUG_SET_TIME; 2639 | set_current_state(TASK_RUNNING); 2640 | 2641 | ret = tpd_i2c_read(i2c_client, &pucPoint[0], 1, 0x80); 2642 | //taikoto_test 2643 | printk("***********************111111pucPoint[0] = %d\n",pucPoint[0]); 2644 | TPD_DEBUG("[mtk-tpd] Query status= 0x%x\n", pucPoint[0]); 2645 | if (!( pucPoint[0] & 0x80 || pucPoint[0] & 0x01 )){ 2646 | TPD_DEBUG("[mtk-tpd] No point information\n"); 2647 | msleep(10); 2648 | continue; 2649 | } 2650 | #ifdef I2C_SUPPORT_RS_DMA 2651 | ret = tpd_i2c_read(i2c_client, &pucPoint[0], 14, 0xE0); 2652 | #else 2653 | //ret = tpd_i2c_read(i2c_client, &cPoint[0], 8, 0xC0); 2654 | //ret += tpd_i2c_read(i2c_client, &ePoint[0], 6, 0xE0); 2655 | 2656 | tpd_i2c_write(i2c_client, Rd_P_buf, 3); 2657 | do 2658 | { 2659 | buffer[0] = 0xFF; 2660 | tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 2661 | } while (buffer[0] & 0x01); 2662 | 2663 | tpd_i2c_write(i2c_client, Rd_keep, 4); 2664 | do 2665 | { 2666 | buffer[0] = 0xFF; 2667 | tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 2668 | } while (buffer[0] & 0x01); 2669 | 2670 | ret = tpd_i2c_read(i2c_client, &ePoint[0], 6, 0xA0); 2671 | 2672 | 2673 | tpd_i2c_write(i2c_client, Rd_final, 4); 2674 | do 2675 | { 2676 | buffer[0] = 0xFF; 2677 | tpd_i2c_read(i2c_client, &buffer[0], 1, 0x80); 2678 | } while (buffer[0] & 0x01); 2679 | 2680 | ret += tpd_i2c_read(i2c_client, &cPoint[0], 8, 0xA0); 2681 | 2682 | 2683 | for(i=0; i<6; i++) pucPoint[i] = ePoint[i]; 2684 | for(i=0; i<8; i++) pucPoint[i+6] = cPoint[i]; 2685 | #endif 2686 | /* 2687 | printk("***********************pucPoint[0] = %d\n",pucPoint[0]); 2688 | printk("***********************pucPoint[1] = %d\n",pucPoint[1]); 2689 | printk("***********************pucPoint[2] = %d\n",pucPoint[2]); 2690 | */ 2691 | #ifdef I2C_SUPPORT_RS_DMA 2692 | if (ret == 0xF01) { 2693 | #else 2694 | if (ret == 0xE02) { 2695 | #endif 2696 | // gesture 2697 | if (pucPoint[0] & 0xF0) { 2698 | //printk("-----------------------------------------------pucPoint[0] & 0xF0---------------------.\n"); 2699 | #ifdef TPD_HAVE_PHYSICAL_BUTTON 2700 | //physical key 2701 | if ( pucPoint[0] & 0x40 && pucPoint[0] & 0x01){ 2702 | printk("-----------------------------------------------physical key---------------------.\n"); 2703 | printk("***********************pucPoint[1] = %d\n",pucPoint[1]); 2704 | if ( pucPoint[2] ){//taikoto 20171108 add 2705 | switch (pucPoint[1]) { 2706 | case 1: 2707 | { 2708 | printk("-------------taikoto20171108------------pucPoint[2]-------[HOME]----------.\n"); 2709 | //tpd_button(tpd_keys_dim_local[pucPoint[1]-1][0], tpd_keys_dim_local[pucPoint[1]-1][1], 1); 2710 | input_report_key(kpd_input_dev, KEY_HOME, 1); 2711 | input_sync(kpd_input_dev); 2712 | } 2713 | break; 2714 | case 2: 2715 | { 2716 | printk("-------------taikoto20171108------------pucPoint[2]-------[BACK]----------.\n"); 2717 | //tpd_button(tpd_keys_dim_local[pucPoint[1]-1][0], tpd_keys_dim_local[pucPoint[1]-1][1], 1); 2718 | input_report_key(kpd_input_dev, KEY_BACK, 1); 2719 | input_sync(kpd_input_dev); 2720 | } 2721 | break; 2722 | case 3: 2723 | { 2724 | printk("-------------taikoto20171108------------pucPoint[2]-------[MENU]----------.\n"); 2725 | //tpd_button(tpd_keys_dim_local[pucPoint[1]-1][0], tpd_keys_dim_local[pucPoint[1]-1][1], 1); 2726 | input_report_key(kpd_input_dev, KEY_BACK, 1); 2727 | input_sync(kpd_input_dev); 2728 | } 2729 | break; 2730 | } 2731 | } 2732 | else { 2733 | printk("-------------taikoto20171108------------pucPoint[2]-------down----------.\n"); 2734 | if ( 1 == pucPoint[1] ) { 2735 | input_report_key(kpd_input_dev, KEY_HOME,0); 2736 | } 2737 | if ( 2 == pucPoint[1] ) { 2738 | input_report_key(kpd_input_dev, KEY_BACK,0); 2739 | } 2740 | if ( 3 == pucPoint[1] ) { 2741 | input_report_key(kpd_input_dev, KEY_MENU,0); 2742 | } 2743 | input_sync(kpd_input_dev); 2744 | //taikoto 20171108 end 2745 | } 2746 | } else 2747 | #endif 2748 | { 2749 | TPD_DEBUG("[mtk-tpd] it's a button/gesture\n"); 2750 | continue; 2751 | } 2752 | } 2753 | // palm 2754 | else if( pucPoint[1] & 0x01 ) { 2755 | TPD_DEBUG("[mtk-tpd] it's a palm\n"); 2756 | continue; 2757 | } 2758 | // no more data 2759 | else if (!(pucPoint[0] & 0x08)) { 2760 | if( finger[0] ){ 2761 | finger[0] = 0; 2762 | tpd_up(x[0], y[0], x[0], y[0], 0); 2763 | flag = 1; 2764 | } 2765 | if( finger[1] ){ 2766 | finger[1] = 0; 2767 | tpd_up(x[1], y[1], x[1], y[1], 0); 2768 | flag = 1; 2769 | } 2770 | if( flag ){ 2771 | flag = 0; 2772 | input_sync(tpd->dev); 2773 | } 2774 | TPD_DEBUG("[mtk-tpd] no more data\n"); 2775 | continue; 2776 | } 2777 | // 3 fingers 2778 | else if (pucPoint[0] & 0x04) { 2779 | TPD_DEBUG("[mtk-tpd] we don't support three fingers\n"); 2780 | continue; 2781 | } 2782 | else{ 2783 | // finger 1 2784 | if (pucPoint[0] & 0x01) { 2785 | //char pressure_point; 2786 | 2787 | xraw = ((pucPoint[3] & 0x0F) << 8) + pucPoint[2]; 2788 | yraw = ((pucPoint[3] & 0xF0) << 4) + pucPoint[4]; 2789 | //pressure_point = pucPoint[5] & 0x0f; 2790 | //TPD_DEBUG("[mtk-tpd] input Read_Point1 x=%d y=%d p=%d\n",xraw,yraw,pressure_point); 2791 | //tpd_calibrate(&xraw, &yraw); 2792 | x[0] = xraw; //by FHH 2793 | y[0] = yraw; 2794 | finger[0] = 1; 2795 | //printk("***********************x[0] = %d,y[0]=%d\n",x[0],y[0]); 2796 | tpd_down(x[0], y[0], x[0], y[0], 0); 2797 | printk("*******************tpd_down:x0=%d,y0=%d\n",x[0],y[0]); 2798 | } 2799 | else if( finger[0] ){ 2800 | tpd_up(x[0], y[0], x[0], y[0], 0); 2801 | finger[0] = 0; 2802 | } 2803 | 2804 | // finger 2 2805 | if (pucPoint[0] & 0x02) { 2806 | //char pressure_point; 2807 | xraw = ((pucPoint[7] & 0x0F) << 8) + pucPoint[6]; 2808 | yraw = ((pucPoint[7] & 0xF0) << 4) + pucPoint[8]; 2809 | //pressure_point = pucPoint[9] & 0x0f; 2810 | //TPD_DEBUG("[mtk-tpd] input Read_Point2 x=%d y=%d p=%d\n",xraw,yraw,pressure_point); 2811 | // tpd_calibrate(&xraw, &yraw); 2812 | x[1] = xraw; 2813 | y[1] = yraw; 2814 | finger[1] = 1; 2815 | tpd_down(x[1], y[1], x[1], y[1], 1); 2816 | printk("*******************tpd_down:x1=%d,y1=%d\n",x[1],y[1]); 2817 | } else if (finger[1]){ 2818 | tpd_up(x[1], y[1], x[1], y[1], 0); 2819 | finger[1] = 0; 2820 | } 2821 | input_sync(tpd->dev); 2822 | } 2823 | }else{ 2824 | TPD_DEBUG("[mtk-tpd] i2c read communcate error in getting pixels : 0x%x\n", ret); 2825 | } 2826 | } while (!kthread_should_stop()); 2827 | return 0; 2828 | } 2829 | 2830 | int tpd_local_init(void) 2831 | { 2832 | int r; 2833 | int ret; 2834 | ///TPD_DMESG("Focaltech it7259 I2C Touchscreen Driver (Built %s @ %s)\n", __DATE__, __TIME__); 2835 | //power on, need confirm with SA 2836 | #if 1 //def CONFIG_ARCH_MT6580 2837 | tpd->reg=regulator_get(tpd->tpd_dev, "vtouch"); // get pointer to regulator structure 2838 | if (IS_ERR(tpd->reg)) { 2839 | printk("taikoto : regulator_get() failed!\n"); 2840 | } 2841 | 2842 | ret=regulator_set_voltage(tpd->reg, 2800000, 2800000); // set 2.8v 2843 | if (ret) 2844 | printk("regulator_set_voltage() failed!\n"); 2845 | ret=regulator_enable(tpd->reg); //enable regulator 2846 | if (ret) 2847 | printk("taikoto : regulator_enable() failed!\n"); 2848 | #else 2849 | //hwPowerOn(TPD_POWER_SOURCE_CUSTOM, VOL_2800, "TP"); 2850 | #endif 2851 | if(i2c_add_driver(&tpd_i2c_driver)!=0) { 2852 | printk("taikoto : unable to add i2c driver.\n"); 2853 | return -1; 2854 | } 2855 | 2856 | /* register device (/dev/IT7259 CTP) */ 2857 | //ctp_dev.parent = tpd->dev; 2858 | r = misc_register(&ctp_dev); 2859 | if (r) { 2860 | printk("taikoto : register ctp device failed (%d)\n", r); 2861 | return -1; 2862 | } 2863 | 2864 | 2865 | 2866 | #if (defined(TPD_WARP_START) && defined(TPD_WARP_END)) 2867 | TPD_DO_WARP = 1; 2868 | memcpy(tpd_wb_start, tpd_wb_start_local, TPD_WARP_CNT*4); 2869 | memcpy(tpd_wb_end, tpd_wb_start_local, TPD_WARP_CNT*4); 2870 | #endif 2871 | 2872 | #if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION)) 2873 | memcpy(tpd_calmat, tpd_def_calmat_local, 8*4); 2874 | memcpy(tpd_def_calmat, tpd_def_calmat_local, 8*4); 2875 | #endif 2876 | printk("end %s, %d\n", __FUNCTION__, __LINE__); 2877 | 2878 | tpd_type_cap = 1; 2879 | 2880 | return 0; 2881 | } 2882 | 2883 | /* Function to manage low power suspend */ 2884 | static void tpd_suspend(struct device *h) 2885 | { 2886 | // int ret = 0; 2887 | // unsigned char Wrbuf[4] = { 0x20, 0x04, 0x00, 0x02 }; 2888 | 2889 | // tpd_halt = 1; 2890 | // mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); 2891 | 2892 | TPD_DEBUG("taikoto : IT7259 call suspend\n"); 2893 | 2894 | // mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); 2895 | disable_irq(touch_irq); 2896 | tpd_halt = 1; 2897 | tpd_gpio_output(GTP_RST_PORT, 0); 2898 | msleep(100); 2899 | /* //by FHH 2900 | TPD_DEBUG("IT7259 call suspend\n"); 2901 | ret = tpd_i2c_write(i2c_client, Wrbuf, 4); 2902 | msleep(100); 2903 | 2904 | if(ret != 4){ 2905 | TPD_DEBUG("[mtk-tpd] i2c write communcate error during suspend: 0x%x\n", ret); 2906 | } 2907 | msleep(200); 2908 | */ 2909 | //hwPowerDown(MT65XX_POWER_LDO_VGP2, "TP"); 2910 | } 2911 | 2912 | /* Function to manage power-on resume */ 2913 | static void tpd_resume(struct device *h) 2914 | { 2915 | #define TRY_COUNTS 5 2916 | int i=0; 2917 | int ret = 0; 2918 | unsigned char Wrbuf[2] = { 0x20, 0x6F}; 2919 | char gsbuffer[2]; 2920 | #if 0 // 1 //by FHH 2921 | mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO); 2922 | mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT); 2923 | mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ZERO); 2924 | msleep(100); 2925 | mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE ); 2926 | #else 2927 | tpd_gpio_output(GTP_RST_PORT, 1); //ugrec_tky gpio_direction_output(tpd_rst_gpio_number, 0); 2928 | msleep(100); 2929 | tpd_gpio_output(GTP_RST_PORT, 0); //ugrec_tky gpio_direction_output(tpd_rst_gpio_number, 1); 2930 | msleep(200); 2931 | tpd_gpio_output(GTP_RST_PORT, 1); //ugrec_tky gpio_direction_output(tpd_rst_gpio_number, 1); 2932 | #endif 2933 | for(i=0;idev); 2950 | } 2951 | 2952 | static struct tpd_driver_t tpd_device_driver = { 2953 | //.tpd_device_name = "IT7259", 2954 | .tpd_device_name =CTP_NAME, // TPD_DEVICE, 2955 | .tpd_local_init = tpd_local_init, 2956 | .suspend = tpd_suspend, 2957 | .resume = tpd_resume, 2958 | #ifdef TPD_HAVE_BUTTON 2959 | .tpd_have_button = 1, 2960 | #else 2961 | .tpd_have_button = 0, 2962 | #endif 2963 | }; 2964 | 2965 | /* 2966 | static bool waitCommandDone(void) 2967 | { 2968 | unsigned char ucQuery = 0xFF; 2969 | unsigned int count = 0; 2970 | 2971 | do{ 2972 | ucQuery = 0xFF; 2973 | tpd_i2c_read(i2c_client, &ucQuery, 1, 0x80); 2974 | count++; 2975 | }while(ucQuery & 0x01 && count < 500); 2976 | 2977 | if( !(ucQuery & 0x01) ){ 2978 | return true; 2979 | }else{ 2980 | printk("XXX %s, %d\n", __FUNCTION__, __LINE__); 2981 | return false; 2982 | } 2983 | } 2984 | */ 2985 | 2986 | /* called when loaded into kernel */ 2987 | static int __init tpd_driver_init(void) 2988 | { 2989 | tpd_get_dts_info(); 2990 | printk("taikoto : MediaTek IT7259 touch panel driver init\n"); 2991 | #if defined(TPD_I2C_NUMBER) //lshun modify 20130615 2992 | // i2c_register_board_info(TPD_I2C_NUMBER, &it7259_i2c_tpd, 1); 2993 | #else 2994 | // i2c_register_board_info(0, &it7259_i2c_tpd, 0); 2995 | #endif 2996 | if(tpd_driver_add(&tpd_device_driver) < 0) 2997 | printk("add generic driver failed\n"); 2998 | 2999 | return 0; 3000 | } 3001 | 3002 | /* should never be called */ 3003 | static void __exit tpd_driver_exit(void) 3004 | { 3005 | printk("taikoto : MediaTek IT7259 touch panel driver exit\n"); 3006 | //input_unregister_device(tpd->dev); 3007 | tpd_driver_remove(&tpd_device_driver); 3008 | } 3009 | 3010 | 3011 | module_init(tpd_driver_init); 3012 | module_exit(tpd_driver_exit); 3013 | 3014 | -------------------------------------------------------------------------------- /documents/LIS2DH12/lis2dh12.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/LIS2DH12/lis2dh12.pdf -------------------------------------------------------------------------------- /documents/LPM013M126C/5LL_1.28_square_BL_LPM013M126C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/LPM013M126C/5LL_1.28_square_BL_LPM013M126C.pdf -------------------------------------------------------------------------------- /documents/LPM013M126C/5LPM013M126C_specification_ver03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/LPM013M126C/5LPM013M126C_specification_ver03.pdf -------------------------------------------------------------------------------- /documents/STM32L476JEY6/DS10198.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/STM32L476JEY6/DS10198.pdf -------------------------------------------------------------------------------- /documents/STM32L476JEY6/PM0214.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/STM32L476JEY6/PM0214.pdf -------------------------------------------------------------------------------- /documents/STM32L476JEY6/RM0351.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/STM32L476JEY6/RM0351.pdf -------------------------------------------------------------------------------- /documents/TPS62743/tps62743.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/documents/TPS62743/tps62743.pdf -------------------------------------------------------------------------------- /images/Amazfit_BIP_LCD_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/images/Amazfit_BIP_LCD_00.png -------------------------------------------------------------------------------- /images/Amazfit_BIP_biosensors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/images/Amazfit_BIP_biosensors.png -------------------------------------------------------------------------------- /images/Amazfit_BIP_bot_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/images/Amazfit_BIP_bot_00.png -------------------------------------------------------------------------------- /images/Amazfit_BIP_top_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amazfitbip/documentation/9c2497b3ced8301eac60567f80bcb3b48a21a5eb/images/Amazfit_BIP_top_00.png --------------------------------------------------------------------------------