1*2b6a321dSAndrew Duggan /* 2*2b6a321dSAndrew Duggan * Copyright (c) 2011-2016 Synaptics Incorporated 3*2b6a321dSAndrew Duggan * Copyright (c) 2011 Unixphere 4*2b6a321dSAndrew Duggan * 5*2b6a321dSAndrew Duggan * This program is free software; you can redistribute it and/or modify it 6*2b6a321dSAndrew Duggan * under the terms of the GNU General Public License version 2 as published by 7*2b6a321dSAndrew Duggan * the Free Software Foundation. 8*2b6a321dSAndrew Duggan */ 9*2b6a321dSAndrew Duggan 10*2b6a321dSAndrew Duggan #include <linux/kernel.h> 11*2b6a321dSAndrew Duggan #include <linux/kconfig.h> 12*2b6a321dSAndrew Duggan #include <linux/rmi.h> 13*2b6a321dSAndrew Duggan #include <linux/slab.h> 14*2b6a321dSAndrew Duggan #include <linux/uaccess.h> 15*2b6a321dSAndrew Duggan #include <linux/of.h> 16*2b6a321dSAndrew Duggan #include "rmi_driver.h" 17*2b6a321dSAndrew Duggan 18*2b6a321dSAndrew Duggan #define RMI_PRODUCT_ID_LENGTH 10 19*2b6a321dSAndrew Duggan #define RMI_PRODUCT_INFO_LENGTH 2 20*2b6a321dSAndrew Duggan 21*2b6a321dSAndrew Duggan #define RMI_DATE_CODE_LENGTH 3 22*2b6a321dSAndrew Duggan 23*2b6a321dSAndrew Duggan #define PRODUCT_ID_OFFSET 0x10 24*2b6a321dSAndrew Duggan #define PRODUCT_INFO_OFFSET 0x1E 25*2b6a321dSAndrew Duggan 26*2b6a321dSAndrew Duggan 27*2b6a321dSAndrew Duggan /* Force a firmware reset of the sensor */ 28*2b6a321dSAndrew Duggan #define RMI_F01_CMD_DEVICE_RESET 1 29*2b6a321dSAndrew Duggan 30*2b6a321dSAndrew Duggan /* Various F01_RMI_QueryX bits */ 31*2b6a321dSAndrew Duggan 32*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_CUSTOM_MAP BIT(0) 33*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_NON_COMPLIANT BIT(1) 34*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_LTS BIT(2) 35*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_SENSOR_ID BIT(3) 36*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_CHARGER_INP BIT(4) 37*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_ADJ_DOZE BIT(5) 38*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_ADJ_DOZE_HOFF BIT(6) 39*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_QUERY42 BIT(7) 40*2b6a321dSAndrew Duggan 41*2b6a321dSAndrew Duggan #define RMI_F01_QRY5_YEAR_MASK 0x1f 42*2b6a321dSAndrew Duggan #define RMI_F01_QRY6_MONTH_MASK 0x0f 43*2b6a321dSAndrew Duggan #define RMI_F01_QRY7_DAY_MASK 0x1f 44*2b6a321dSAndrew Duggan 45*2b6a321dSAndrew Duggan #define RMI_F01_QRY2_PRODINFO_MASK 0x7f 46*2b6a321dSAndrew Duggan 47*2b6a321dSAndrew Duggan #define RMI_F01_BASIC_QUERY_LEN 21 /* From Query 00 through 20 */ 48*2b6a321dSAndrew Duggan 49*2b6a321dSAndrew Duggan struct f01_basic_properties { 50*2b6a321dSAndrew Duggan u8 manufacturer_id; 51*2b6a321dSAndrew Duggan bool has_lts; 52*2b6a321dSAndrew Duggan bool has_adjustable_doze; 53*2b6a321dSAndrew Duggan bool has_adjustable_doze_holdoff; 54*2b6a321dSAndrew Duggan char dom[11]; /* YYYY/MM/DD + '\0' */ 55*2b6a321dSAndrew Duggan u8 product_id[RMI_PRODUCT_ID_LENGTH + 1]; 56*2b6a321dSAndrew Duggan u16 productinfo; 57*2b6a321dSAndrew Duggan u32 firmware_id; 58*2b6a321dSAndrew Duggan }; 59*2b6a321dSAndrew Duggan 60*2b6a321dSAndrew Duggan /* F01 device status bits */ 61*2b6a321dSAndrew Duggan 62*2b6a321dSAndrew Duggan /* Most recent device status event */ 63*2b6a321dSAndrew Duggan #define RMI_F01_STATUS_CODE(status) ((status) & 0x0f) 64*2b6a321dSAndrew Duggan /* The device has lost its configuration for some reason. */ 65*2b6a321dSAndrew Duggan #define RMI_F01_STATUS_UNCONFIGURED(status) (!!((status) & 0x80)) 66*2b6a321dSAndrew Duggan 67*2b6a321dSAndrew Duggan /* Control register bits */ 68*2b6a321dSAndrew Duggan 69*2b6a321dSAndrew Duggan /* 70*2b6a321dSAndrew Duggan * Sleep mode controls power management on the device and affects all 71*2b6a321dSAndrew Duggan * functions of the device. 72*2b6a321dSAndrew Duggan */ 73*2b6a321dSAndrew Duggan #define RMI_F01_CTRL0_SLEEP_MODE_MASK 0x03 74*2b6a321dSAndrew Duggan 75*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_NORMAL 0x00 76*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_SENSOR_SLEEP 0x01 77*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_RESERVED0 0x02 78*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_RESERVED1 0x03 79*2b6a321dSAndrew Duggan 80*2b6a321dSAndrew Duggan /* 81*2b6a321dSAndrew Duggan * This bit disables whatever sleep mode may be selected by the sleep_mode 82*2b6a321dSAndrew Duggan * field and forces the device to run at full power without sleeping. 83*2b6a321dSAndrew Duggan */ 84*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_NOSLEEP_BIT BIT(2) 85*2b6a321dSAndrew Duggan 86*2b6a321dSAndrew Duggan /* 87*2b6a321dSAndrew Duggan * When this bit is set, the touch controller employs a noise-filtering 88*2b6a321dSAndrew Duggan * algorithm designed for use with a connected battery charger. 89*2b6a321dSAndrew Duggan */ 90*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_CHARGER_BIT BIT(5) 91*2b6a321dSAndrew Duggan 92*2b6a321dSAndrew Duggan /* 93*2b6a321dSAndrew Duggan * Sets the report rate for the device. The effect of this setting is 94*2b6a321dSAndrew Duggan * highly product dependent. Check the spec sheet for your particular 95*2b6a321dSAndrew Duggan * touch sensor. 96*2b6a321dSAndrew Duggan */ 97*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_REPORTRATE_BIT BIT(6) 98*2b6a321dSAndrew Duggan 99*2b6a321dSAndrew Duggan /* 100*2b6a321dSAndrew Duggan * Written by the host as an indicator that the device has been 101*2b6a321dSAndrew Duggan * successfully configured. 102*2b6a321dSAndrew Duggan */ 103*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_CONFIGURED_BIT BIT(7) 104*2b6a321dSAndrew Duggan 105*2b6a321dSAndrew Duggan /** 106*2b6a321dSAndrew Duggan * @ctrl0 - see the bit definitions above. 107*2b6a321dSAndrew Duggan * @doze_interval - controls the interval between checks for finger presence 108*2b6a321dSAndrew Duggan * when the touch sensor is in doze mode, in units of 10ms. 109*2b6a321dSAndrew Duggan * @wakeup_threshold - controls the capacitance threshold at which the touch 110*2b6a321dSAndrew Duggan * sensor will decide to wake up from that low power state. 111*2b6a321dSAndrew Duggan * @doze_holdoff - controls how long the touch sensor waits after the last 112*2b6a321dSAndrew Duggan * finger lifts before entering the doze state, in units of 100ms. 113*2b6a321dSAndrew Duggan */ 114*2b6a321dSAndrew Duggan struct f01_device_control { 115*2b6a321dSAndrew Duggan u8 ctrl0; 116*2b6a321dSAndrew Duggan u8 doze_interval; 117*2b6a321dSAndrew Duggan u8 wakeup_threshold; 118*2b6a321dSAndrew Duggan u8 doze_holdoff; 119*2b6a321dSAndrew Duggan }; 120*2b6a321dSAndrew Duggan 121*2b6a321dSAndrew Duggan struct f01_data { 122*2b6a321dSAndrew Duggan struct f01_basic_properties properties; 123*2b6a321dSAndrew Duggan struct f01_device_control device_control; 124*2b6a321dSAndrew Duggan 125*2b6a321dSAndrew Duggan u16 doze_interval_addr; 126*2b6a321dSAndrew Duggan u16 wakeup_threshold_addr; 127*2b6a321dSAndrew Duggan u16 doze_holdoff_addr; 128*2b6a321dSAndrew Duggan 129*2b6a321dSAndrew Duggan bool suspended; 130*2b6a321dSAndrew Duggan bool old_nosleep; 131*2b6a321dSAndrew Duggan 132*2b6a321dSAndrew Duggan unsigned int num_of_irq_regs; 133*2b6a321dSAndrew Duggan }; 134*2b6a321dSAndrew Duggan 135*2b6a321dSAndrew Duggan static int rmi_f01_read_properties(struct rmi_device *rmi_dev, 136*2b6a321dSAndrew Duggan u16 query_base_addr, 137*2b6a321dSAndrew Duggan struct f01_basic_properties *props) 138*2b6a321dSAndrew Duggan { 139*2b6a321dSAndrew Duggan u8 queries[RMI_F01_BASIC_QUERY_LEN]; 140*2b6a321dSAndrew Duggan int ret; 141*2b6a321dSAndrew Duggan int query_offset = query_base_addr; 142*2b6a321dSAndrew Duggan bool has_ds4_queries = false; 143*2b6a321dSAndrew Duggan bool has_query42 = false; 144*2b6a321dSAndrew Duggan bool has_sensor_id = false; 145*2b6a321dSAndrew Duggan bool has_package_id_query = false; 146*2b6a321dSAndrew Duggan bool has_build_id_query = false; 147*2b6a321dSAndrew Duggan u16 prod_info_addr; 148*2b6a321dSAndrew Duggan u8 ds4_query_len; 149*2b6a321dSAndrew Duggan 150*2b6a321dSAndrew Duggan ret = rmi_read_block(rmi_dev, query_offset, 151*2b6a321dSAndrew Duggan queries, RMI_F01_BASIC_QUERY_LEN); 152*2b6a321dSAndrew Duggan if (ret) { 153*2b6a321dSAndrew Duggan dev_err(&rmi_dev->dev, 154*2b6a321dSAndrew Duggan "Failed to read device query registers: %d\n", ret); 155*2b6a321dSAndrew Duggan return ret; 156*2b6a321dSAndrew Duggan } 157*2b6a321dSAndrew Duggan 158*2b6a321dSAndrew Duggan prod_info_addr = query_offset + 17; 159*2b6a321dSAndrew Duggan query_offset += RMI_F01_BASIC_QUERY_LEN; 160*2b6a321dSAndrew Duggan 161*2b6a321dSAndrew Duggan /* Now parse what we got */ 162*2b6a321dSAndrew Duggan props->manufacturer_id = queries[0]; 163*2b6a321dSAndrew Duggan 164*2b6a321dSAndrew Duggan props->has_lts = queries[1] & RMI_F01_QRY1_HAS_LTS; 165*2b6a321dSAndrew Duggan props->has_adjustable_doze = 166*2b6a321dSAndrew Duggan queries[1] & RMI_F01_QRY1_HAS_ADJ_DOZE; 167*2b6a321dSAndrew Duggan props->has_adjustable_doze_holdoff = 168*2b6a321dSAndrew Duggan queries[1] & RMI_F01_QRY1_HAS_ADJ_DOZE_HOFF; 169*2b6a321dSAndrew Duggan has_query42 = queries[1] & RMI_F01_QRY1_HAS_QUERY42; 170*2b6a321dSAndrew Duggan has_sensor_id = queries[1] & RMI_F01_QRY1_HAS_SENSOR_ID; 171*2b6a321dSAndrew Duggan 172*2b6a321dSAndrew Duggan snprintf(props->dom, sizeof(props->dom), "20%02d/%02d/%02d", 173*2b6a321dSAndrew Duggan queries[5] & RMI_F01_QRY5_YEAR_MASK, 174*2b6a321dSAndrew Duggan queries[6] & RMI_F01_QRY6_MONTH_MASK, 175*2b6a321dSAndrew Duggan queries[7] & RMI_F01_QRY7_DAY_MASK); 176*2b6a321dSAndrew Duggan 177*2b6a321dSAndrew Duggan memcpy(props->product_id, &queries[11], 178*2b6a321dSAndrew Duggan RMI_PRODUCT_ID_LENGTH); 179*2b6a321dSAndrew Duggan props->product_id[RMI_PRODUCT_ID_LENGTH] = '\0'; 180*2b6a321dSAndrew Duggan 181*2b6a321dSAndrew Duggan props->productinfo = 182*2b6a321dSAndrew Duggan ((queries[2] & RMI_F01_QRY2_PRODINFO_MASK) << 7) | 183*2b6a321dSAndrew Duggan (queries[3] & RMI_F01_QRY2_PRODINFO_MASK); 184*2b6a321dSAndrew Duggan 185*2b6a321dSAndrew Duggan if (has_sensor_id) 186*2b6a321dSAndrew Duggan query_offset++; 187*2b6a321dSAndrew Duggan 188*2b6a321dSAndrew Duggan if (has_query42) { 189*2b6a321dSAndrew Duggan ret = rmi_read(rmi_dev, query_offset, queries); 190*2b6a321dSAndrew Duggan if (ret) { 191*2b6a321dSAndrew Duggan dev_err(&rmi_dev->dev, 192*2b6a321dSAndrew Duggan "Failed to read query 42 register: %d\n", ret); 193*2b6a321dSAndrew Duggan return ret; 194*2b6a321dSAndrew Duggan } 195*2b6a321dSAndrew Duggan 196*2b6a321dSAndrew Duggan has_ds4_queries = !!(queries[0] & BIT(0)); 197*2b6a321dSAndrew Duggan query_offset++; 198*2b6a321dSAndrew Duggan } 199*2b6a321dSAndrew Duggan 200*2b6a321dSAndrew Duggan if (has_ds4_queries) { 201*2b6a321dSAndrew Duggan ret = rmi_read(rmi_dev, query_offset, &ds4_query_len); 202*2b6a321dSAndrew Duggan if (ret) { 203*2b6a321dSAndrew Duggan dev_err(&rmi_dev->dev, 204*2b6a321dSAndrew Duggan "Failed to read DS4 queries length: %d\n", ret); 205*2b6a321dSAndrew Duggan return ret; 206*2b6a321dSAndrew Duggan } 207*2b6a321dSAndrew Duggan query_offset++; 208*2b6a321dSAndrew Duggan 209*2b6a321dSAndrew Duggan if (ds4_query_len > 0) { 210*2b6a321dSAndrew Duggan ret = rmi_read(rmi_dev, query_offset, queries); 211*2b6a321dSAndrew Duggan if (ret) { 212*2b6a321dSAndrew Duggan dev_err(&rmi_dev->dev, 213*2b6a321dSAndrew Duggan "Failed to read DS4 queries: %d\n", 214*2b6a321dSAndrew Duggan ret); 215*2b6a321dSAndrew Duggan return ret; 216*2b6a321dSAndrew Duggan } 217*2b6a321dSAndrew Duggan 218*2b6a321dSAndrew Duggan has_package_id_query = !!(queries[0] & BIT(0)); 219*2b6a321dSAndrew Duggan has_build_id_query = !!(queries[0] & BIT(1)); 220*2b6a321dSAndrew Duggan } 221*2b6a321dSAndrew Duggan 222*2b6a321dSAndrew Duggan if (has_package_id_query) 223*2b6a321dSAndrew Duggan prod_info_addr++; 224*2b6a321dSAndrew Duggan 225*2b6a321dSAndrew Duggan if (has_build_id_query) { 226*2b6a321dSAndrew Duggan ret = rmi_read_block(rmi_dev, prod_info_addr, queries, 227*2b6a321dSAndrew Duggan 3); 228*2b6a321dSAndrew Duggan if (ret) { 229*2b6a321dSAndrew Duggan dev_err(&rmi_dev->dev, 230*2b6a321dSAndrew Duggan "Failed to read product info: %d\n", 231*2b6a321dSAndrew Duggan ret); 232*2b6a321dSAndrew Duggan return ret; 233*2b6a321dSAndrew Duggan } 234*2b6a321dSAndrew Duggan 235*2b6a321dSAndrew Duggan props->firmware_id = queries[1] << 8 | queries[0]; 236*2b6a321dSAndrew Duggan props->firmware_id += queries[2] * 65536; 237*2b6a321dSAndrew Duggan } 238*2b6a321dSAndrew Duggan } 239*2b6a321dSAndrew Duggan 240*2b6a321dSAndrew Duggan return 0; 241*2b6a321dSAndrew Duggan } 242*2b6a321dSAndrew Duggan 243*2b6a321dSAndrew Duggan char *rmi_f01_get_product_ID(struct rmi_function *fn) 244*2b6a321dSAndrew Duggan { 245*2b6a321dSAndrew Duggan struct f01_data *f01 = dev_get_drvdata(&fn->dev); 246*2b6a321dSAndrew Duggan 247*2b6a321dSAndrew Duggan return f01->properties.product_id; 248*2b6a321dSAndrew Duggan } 249*2b6a321dSAndrew Duggan 250*2b6a321dSAndrew Duggan static int rmi_f01_probe(struct rmi_function *fn) 251*2b6a321dSAndrew Duggan { 252*2b6a321dSAndrew Duggan struct rmi_device *rmi_dev = fn->rmi_dev; 253*2b6a321dSAndrew Duggan struct rmi_driver_data *driver_data = dev_get_drvdata(&rmi_dev->dev); 254*2b6a321dSAndrew Duggan struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); 255*2b6a321dSAndrew Duggan struct f01_data *f01; 256*2b6a321dSAndrew Duggan int error; 257*2b6a321dSAndrew Duggan u16 ctrl_base_addr = fn->fd.control_base_addr; 258*2b6a321dSAndrew Duggan u8 device_status; 259*2b6a321dSAndrew Duggan u8 temp; 260*2b6a321dSAndrew Duggan 261*2b6a321dSAndrew Duggan f01 = devm_kzalloc(&fn->dev, sizeof(struct f01_data), GFP_KERNEL); 262*2b6a321dSAndrew Duggan if (!f01) 263*2b6a321dSAndrew Duggan return -ENOMEM; 264*2b6a321dSAndrew Duggan 265*2b6a321dSAndrew Duggan f01->num_of_irq_regs = driver_data->num_of_irq_regs; 266*2b6a321dSAndrew Duggan 267*2b6a321dSAndrew Duggan /* 268*2b6a321dSAndrew Duggan * Set the configured bit and (optionally) other important stuff 269*2b6a321dSAndrew Duggan * in the device control register. 270*2b6a321dSAndrew Duggan */ 271*2b6a321dSAndrew Duggan 272*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, fn->fd.control_base_addr, 273*2b6a321dSAndrew Duggan &f01->device_control.ctrl0); 274*2b6a321dSAndrew Duggan if (error) { 275*2b6a321dSAndrew Duggan dev_err(&fn->dev, "Failed to read F01 control: %d\n", error); 276*2b6a321dSAndrew Duggan return error; 277*2b6a321dSAndrew Duggan } 278*2b6a321dSAndrew Duggan 279*2b6a321dSAndrew Duggan switch (pdata->power_management.nosleep) { 280*2b6a321dSAndrew Duggan case RMI_F01_NOSLEEP_DEFAULT: 281*2b6a321dSAndrew Duggan break; 282*2b6a321dSAndrew Duggan case RMI_F01_NOSLEEP_OFF: 283*2b6a321dSAndrew Duggan f01->device_control.ctrl0 &= ~RMI_F01_CRTL0_NOSLEEP_BIT; 284*2b6a321dSAndrew Duggan break; 285*2b6a321dSAndrew Duggan case RMI_F01_NOSLEEP_ON: 286*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT; 287*2b6a321dSAndrew Duggan break; 288*2b6a321dSAndrew Duggan } 289*2b6a321dSAndrew Duggan 290*2b6a321dSAndrew Duggan /* 291*2b6a321dSAndrew Duggan * Sleep mode might be set as a hangover from a system crash or 292*2b6a321dSAndrew Duggan * reboot without power cycle. If so, clear it so the sensor 293*2b6a321dSAndrew Duggan * is certain to function. 294*2b6a321dSAndrew Duggan */ 295*2b6a321dSAndrew Duggan if ((f01->device_control.ctrl0 & RMI_F01_CTRL0_SLEEP_MODE_MASK) != 296*2b6a321dSAndrew Duggan RMI_SLEEP_MODE_NORMAL) { 297*2b6a321dSAndrew Duggan dev_warn(&fn->dev, 298*2b6a321dSAndrew Duggan "WARNING: Non-zero sleep mode found. Clearing...\n"); 299*2b6a321dSAndrew Duggan f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; 300*2b6a321dSAndrew Duggan } 301*2b6a321dSAndrew Duggan 302*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT; 303*2b6a321dSAndrew Duggan 304*2b6a321dSAndrew Duggan error = rmi_write(rmi_dev, fn->fd.control_base_addr, 305*2b6a321dSAndrew Duggan f01->device_control.ctrl0); 306*2b6a321dSAndrew Duggan if (error) { 307*2b6a321dSAndrew Duggan dev_err(&fn->dev, "Failed to write F01 control: %d\n", error); 308*2b6a321dSAndrew Duggan return error; 309*2b6a321dSAndrew Duggan } 310*2b6a321dSAndrew Duggan 311*2b6a321dSAndrew Duggan /* Dummy read in order to clear irqs */ 312*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, fn->fd.data_base_addr + 1, &temp); 313*2b6a321dSAndrew Duggan if (error < 0) { 314*2b6a321dSAndrew Duggan dev_err(&fn->dev, "Failed to read Interrupt Status.\n"); 315*2b6a321dSAndrew Duggan return error; 316*2b6a321dSAndrew Duggan } 317*2b6a321dSAndrew Duggan 318*2b6a321dSAndrew Duggan error = rmi_f01_read_properties(rmi_dev, fn->fd.query_base_addr, 319*2b6a321dSAndrew Duggan &f01->properties); 320*2b6a321dSAndrew Duggan if (error < 0) { 321*2b6a321dSAndrew Duggan dev_err(&fn->dev, "Failed to read F01 properties.\n"); 322*2b6a321dSAndrew Duggan return error; 323*2b6a321dSAndrew Duggan } 324*2b6a321dSAndrew Duggan 325*2b6a321dSAndrew Duggan dev_info(&fn->dev, "found RMI device, manufacturer: %s, product: %s, fw id: %d\n", 326*2b6a321dSAndrew Duggan f01->properties.manufacturer_id == 1 ? "Synaptics" : "unknown", 327*2b6a321dSAndrew Duggan f01->properties.product_id, f01->properties.firmware_id); 328*2b6a321dSAndrew Duggan 329*2b6a321dSAndrew Duggan /* Advance to interrupt control registers, then skip over them. */ 330*2b6a321dSAndrew Duggan ctrl_base_addr++; 331*2b6a321dSAndrew Duggan ctrl_base_addr += f01->num_of_irq_regs; 332*2b6a321dSAndrew Duggan 333*2b6a321dSAndrew Duggan /* read control register */ 334*2b6a321dSAndrew Duggan if (f01->properties.has_adjustable_doze) { 335*2b6a321dSAndrew Duggan f01->doze_interval_addr = ctrl_base_addr; 336*2b6a321dSAndrew Duggan ctrl_base_addr++; 337*2b6a321dSAndrew Duggan 338*2b6a321dSAndrew Duggan if (pdata->power_management.doze_interval) { 339*2b6a321dSAndrew Duggan f01->device_control.doze_interval = 340*2b6a321dSAndrew Duggan pdata->power_management.doze_interval; 341*2b6a321dSAndrew Duggan error = rmi_write(rmi_dev, f01->doze_interval_addr, 342*2b6a321dSAndrew Duggan f01->device_control.doze_interval); 343*2b6a321dSAndrew Duggan if (error) { 344*2b6a321dSAndrew Duggan dev_err(&fn->dev, 345*2b6a321dSAndrew Duggan "Failed to configure F01 doze interval register: %d\n", 346*2b6a321dSAndrew Duggan error); 347*2b6a321dSAndrew Duggan return error; 348*2b6a321dSAndrew Duggan } 349*2b6a321dSAndrew Duggan } else { 350*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, f01->doze_interval_addr, 351*2b6a321dSAndrew Duggan &f01->device_control.doze_interval); 352*2b6a321dSAndrew Duggan if (error) { 353*2b6a321dSAndrew Duggan dev_err(&fn->dev, 354*2b6a321dSAndrew Duggan "Failed to read F01 doze interval register: %d\n", 355*2b6a321dSAndrew Duggan error); 356*2b6a321dSAndrew Duggan return error; 357*2b6a321dSAndrew Duggan } 358*2b6a321dSAndrew Duggan } 359*2b6a321dSAndrew Duggan 360*2b6a321dSAndrew Duggan f01->wakeup_threshold_addr = ctrl_base_addr; 361*2b6a321dSAndrew Duggan ctrl_base_addr++; 362*2b6a321dSAndrew Duggan 363*2b6a321dSAndrew Duggan if (pdata->power_management.wakeup_threshold) { 364*2b6a321dSAndrew Duggan f01->device_control.wakeup_threshold = 365*2b6a321dSAndrew Duggan pdata->power_management.wakeup_threshold; 366*2b6a321dSAndrew Duggan error = rmi_write(rmi_dev, f01->wakeup_threshold_addr, 367*2b6a321dSAndrew Duggan f01->device_control.wakeup_threshold); 368*2b6a321dSAndrew Duggan if (error) { 369*2b6a321dSAndrew Duggan dev_err(&fn->dev, 370*2b6a321dSAndrew Duggan "Failed to configure F01 wakeup threshold register: %d\n", 371*2b6a321dSAndrew Duggan error); 372*2b6a321dSAndrew Duggan return error; 373*2b6a321dSAndrew Duggan } 374*2b6a321dSAndrew Duggan } else { 375*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, f01->wakeup_threshold_addr, 376*2b6a321dSAndrew Duggan &f01->device_control.wakeup_threshold); 377*2b6a321dSAndrew Duggan if (error < 0) { 378*2b6a321dSAndrew Duggan dev_err(&fn->dev, 379*2b6a321dSAndrew Duggan "Failed to read F01 wakeup threshold register: %d\n", 380*2b6a321dSAndrew Duggan error); 381*2b6a321dSAndrew Duggan return error; 382*2b6a321dSAndrew Duggan } 383*2b6a321dSAndrew Duggan } 384*2b6a321dSAndrew Duggan } 385*2b6a321dSAndrew Duggan 386*2b6a321dSAndrew Duggan if (f01->properties.has_lts) 387*2b6a321dSAndrew Duggan ctrl_base_addr++; 388*2b6a321dSAndrew Duggan 389*2b6a321dSAndrew Duggan if (f01->properties.has_adjustable_doze_holdoff) { 390*2b6a321dSAndrew Duggan f01->doze_holdoff_addr = ctrl_base_addr; 391*2b6a321dSAndrew Duggan ctrl_base_addr++; 392*2b6a321dSAndrew Duggan 393*2b6a321dSAndrew Duggan if (pdata->power_management.doze_holdoff) { 394*2b6a321dSAndrew Duggan f01->device_control.doze_holdoff = 395*2b6a321dSAndrew Duggan pdata->power_management.doze_holdoff; 396*2b6a321dSAndrew Duggan error = rmi_write(rmi_dev, f01->doze_holdoff_addr, 397*2b6a321dSAndrew Duggan f01->device_control.doze_holdoff); 398*2b6a321dSAndrew Duggan if (error) { 399*2b6a321dSAndrew Duggan dev_err(&fn->dev, 400*2b6a321dSAndrew Duggan "Failed to configure F01 doze holdoff register: %d\n", 401*2b6a321dSAndrew Duggan error); 402*2b6a321dSAndrew Duggan return error; 403*2b6a321dSAndrew Duggan } 404*2b6a321dSAndrew Duggan } else { 405*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, f01->doze_holdoff_addr, 406*2b6a321dSAndrew Duggan &f01->device_control.doze_holdoff); 407*2b6a321dSAndrew Duggan if (error) { 408*2b6a321dSAndrew Duggan dev_err(&fn->dev, 409*2b6a321dSAndrew Duggan "Failed to read F01 doze holdoff register: %d\n", 410*2b6a321dSAndrew Duggan error); 411*2b6a321dSAndrew Duggan return error; 412*2b6a321dSAndrew Duggan } 413*2b6a321dSAndrew Duggan } 414*2b6a321dSAndrew Duggan } 415*2b6a321dSAndrew Duggan 416*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, fn->fd.data_base_addr, &device_status); 417*2b6a321dSAndrew Duggan if (error < 0) { 418*2b6a321dSAndrew Duggan dev_err(&fn->dev, 419*2b6a321dSAndrew Duggan "Failed to read device status: %d\n", error); 420*2b6a321dSAndrew Duggan return error; 421*2b6a321dSAndrew Duggan } 422*2b6a321dSAndrew Duggan 423*2b6a321dSAndrew Duggan if (RMI_F01_STATUS_UNCONFIGURED(device_status)) { 424*2b6a321dSAndrew Duggan dev_err(&fn->dev, 425*2b6a321dSAndrew Duggan "Device was reset during configuration process, status: %#02x!\n", 426*2b6a321dSAndrew Duggan RMI_F01_STATUS_CODE(device_status)); 427*2b6a321dSAndrew Duggan return -EINVAL; 428*2b6a321dSAndrew Duggan } 429*2b6a321dSAndrew Duggan 430*2b6a321dSAndrew Duggan dev_set_drvdata(&fn->dev, f01); 431*2b6a321dSAndrew Duggan 432*2b6a321dSAndrew Duggan return 0; 433*2b6a321dSAndrew Duggan } 434*2b6a321dSAndrew Duggan 435*2b6a321dSAndrew Duggan static int rmi_f01_config(struct rmi_function *fn) 436*2b6a321dSAndrew Duggan { 437*2b6a321dSAndrew Duggan struct f01_data *f01 = dev_get_drvdata(&fn->dev); 438*2b6a321dSAndrew Duggan int error; 439*2b6a321dSAndrew Duggan 440*2b6a321dSAndrew Duggan error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr, 441*2b6a321dSAndrew Duggan f01->device_control.ctrl0); 442*2b6a321dSAndrew Duggan if (error) { 443*2b6a321dSAndrew Duggan dev_err(&fn->dev, 444*2b6a321dSAndrew Duggan "Failed to write device_control register: %d\n", error); 445*2b6a321dSAndrew Duggan return error; 446*2b6a321dSAndrew Duggan } 447*2b6a321dSAndrew Duggan 448*2b6a321dSAndrew Duggan if (f01->properties.has_adjustable_doze) { 449*2b6a321dSAndrew Duggan error = rmi_write(fn->rmi_dev, f01->doze_interval_addr, 450*2b6a321dSAndrew Duggan f01->device_control.doze_interval); 451*2b6a321dSAndrew Duggan if (error) { 452*2b6a321dSAndrew Duggan dev_err(&fn->dev, 453*2b6a321dSAndrew Duggan "Failed to write doze interval: %d\n", error); 454*2b6a321dSAndrew Duggan return error; 455*2b6a321dSAndrew Duggan } 456*2b6a321dSAndrew Duggan 457*2b6a321dSAndrew Duggan error = rmi_write_block(fn->rmi_dev, 458*2b6a321dSAndrew Duggan f01->wakeup_threshold_addr, 459*2b6a321dSAndrew Duggan &f01->device_control.wakeup_threshold, 460*2b6a321dSAndrew Duggan sizeof(u8)); 461*2b6a321dSAndrew Duggan if (error) { 462*2b6a321dSAndrew Duggan dev_err(&fn->dev, 463*2b6a321dSAndrew Duggan "Failed to write wakeup threshold: %d\n", 464*2b6a321dSAndrew Duggan error); 465*2b6a321dSAndrew Duggan return error; 466*2b6a321dSAndrew Duggan } 467*2b6a321dSAndrew Duggan } 468*2b6a321dSAndrew Duggan 469*2b6a321dSAndrew Duggan if (f01->properties.has_adjustable_doze_holdoff) { 470*2b6a321dSAndrew Duggan error = rmi_write(fn->rmi_dev, f01->doze_holdoff_addr, 471*2b6a321dSAndrew Duggan f01->device_control.doze_holdoff); 472*2b6a321dSAndrew Duggan if (error) { 473*2b6a321dSAndrew Duggan dev_err(&fn->dev, 474*2b6a321dSAndrew Duggan "Failed to write doze holdoff: %d\n", error); 475*2b6a321dSAndrew Duggan return error; 476*2b6a321dSAndrew Duggan } 477*2b6a321dSAndrew Duggan } 478*2b6a321dSAndrew Duggan 479*2b6a321dSAndrew Duggan return 0; 480*2b6a321dSAndrew Duggan } 481*2b6a321dSAndrew Duggan 482*2b6a321dSAndrew Duggan static int rmi_f01_suspend(struct rmi_function *fn) 483*2b6a321dSAndrew Duggan { 484*2b6a321dSAndrew Duggan struct f01_data *f01 = dev_get_drvdata(&fn->dev); 485*2b6a321dSAndrew Duggan int error; 486*2b6a321dSAndrew Duggan 487*2b6a321dSAndrew Duggan f01->old_nosleep = 488*2b6a321dSAndrew Duggan f01->device_control.ctrl0 & RMI_F01_CRTL0_NOSLEEP_BIT; 489*2b6a321dSAndrew Duggan f01->device_control.ctrl0 &= ~RMI_F01_CRTL0_NOSLEEP_BIT; 490*2b6a321dSAndrew Duggan 491*2b6a321dSAndrew Duggan f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; 492*2b6a321dSAndrew Duggan if (device_may_wakeup(fn->rmi_dev->xport->dev)) 493*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_SLEEP_MODE_RESERVED1; 494*2b6a321dSAndrew Duggan else 495*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_SLEEP_MODE_SENSOR_SLEEP; 496*2b6a321dSAndrew Duggan 497*2b6a321dSAndrew Duggan error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr, 498*2b6a321dSAndrew Duggan f01->device_control.ctrl0); 499*2b6a321dSAndrew Duggan if (error) { 500*2b6a321dSAndrew Duggan dev_err(&fn->dev, "Failed to write sleep mode: %d.\n", error); 501*2b6a321dSAndrew Duggan if (f01->old_nosleep) 502*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT; 503*2b6a321dSAndrew Duggan f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; 504*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL; 505*2b6a321dSAndrew Duggan return error; 506*2b6a321dSAndrew Duggan } 507*2b6a321dSAndrew Duggan 508*2b6a321dSAndrew Duggan return 0; 509*2b6a321dSAndrew Duggan } 510*2b6a321dSAndrew Duggan 511*2b6a321dSAndrew Duggan static int rmi_f01_resume(struct rmi_function *fn) 512*2b6a321dSAndrew Duggan { 513*2b6a321dSAndrew Duggan struct f01_data *f01 = dev_get_drvdata(&fn->dev); 514*2b6a321dSAndrew Duggan int error; 515*2b6a321dSAndrew Duggan 516*2b6a321dSAndrew Duggan if (f01->old_nosleep) 517*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT; 518*2b6a321dSAndrew Duggan 519*2b6a321dSAndrew Duggan f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; 520*2b6a321dSAndrew Duggan f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL; 521*2b6a321dSAndrew Duggan 522*2b6a321dSAndrew Duggan error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr, 523*2b6a321dSAndrew Duggan f01->device_control.ctrl0); 524*2b6a321dSAndrew Duggan if (error) { 525*2b6a321dSAndrew Duggan dev_err(&fn->dev, 526*2b6a321dSAndrew Duggan "Failed to restore normal operation: %d.\n", error); 527*2b6a321dSAndrew Duggan return error; 528*2b6a321dSAndrew Duggan } 529*2b6a321dSAndrew Duggan 530*2b6a321dSAndrew Duggan return 0; 531*2b6a321dSAndrew Duggan } 532*2b6a321dSAndrew Duggan 533*2b6a321dSAndrew Duggan static int rmi_f01_attention(struct rmi_function *fn, 534*2b6a321dSAndrew Duggan unsigned long *irq_bits) 535*2b6a321dSAndrew Duggan { 536*2b6a321dSAndrew Duggan struct rmi_device *rmi_dev = fn->rmi_dev; 537*2b6a321dSAndrew Duggan int error; 538*2b6a321dSAndrew Duggan u8 device_status; 539*2b6a321dSAndrew Duggan 540*2b6a321dSAndrew Duggan error = rmi_read(rmi_dev, fn->fd.data_base_addr, &device_status); 541*2b6a321dSAndrew Duggan if (error) { 542*2b6a321dSAndrew Duggan dev_err(&fn->dev, 543*2b6a321dSAndrew Duggan "Failed to read device status: %d.\n", error); 544*2b6a321dSAndrew Duggan return error; 545*2b6a321dSAndrew Duggan } 546*2b6a321dSAndrew Duggan 547*2b6a321dSAndrew Duggan if (RMI_F01_STATUS_UNCONFIGURED(device_status)) { 548*2b6a321dSAndrew Duggan dev_warn(&fn->dev, "Device reset detected.\n"); 549*2b6a321dSAndrew Duggan error = rmi_dev->driver->reset_handler(rmi_dev); 550*2b6a321dSAndrew Duggan if (error) { 551*2b6a321dSAndrew Duggan dev_err(&fn->dev, "Device reset failed: %d\n", error); 552*2b6a321dSAndrew Duggan return error; 553*2b6a321dSAndrew Duggan } 554*2b6a321dSAndrew Duggan } 555*2b6a321dSAndrew Duggan 556*2b6a321dSAndrew Duggan return 0; 557*2b6a321dSAndrew Duggan } 558*2b6a321dSAndrew Duggan 559*2b6a321dSAndrew Duggan struct rmi_function_handler rmi_f01_handler = { 560*2b6a321dSAndrew Duggan .driver = { 561*2b6a321dSAndrew Duggan .name = "rmi4_f01", 562*2b6a321dSAndrew Duggan /* 563*2b6a321dSAndrew Duggan * Do not allow user unbinding F01 as it is critical 564*2b6a321dSAndrew Duggan * function. 565*2b6a321dSAndrew Duggan */ 566*2b6a321dSAndrew Duggan .suppress_bind_attrs = true, 567*2b6a321dSAndrew Duggan }, 568*2b6a321dSAndrew Duggan .func = 0x01, 569*2b6a321dSAndrew Duggan .probe = rmi_f01_probe, 570*2b6a321dSAndrew Duggan .config = rmi_f01_config, 571*2b6a321dSAndrew Duggan .attention = rmi_f01_attention, 572*2b6a321dSAndrew Duggan .suspend = rmi_f01_suspend, 573*2b6a321dSAndrew Duggan .resume = rmi_f01_resume, 574*2b6a321dSAndrew Duggan }; 575