162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2012-2016 Synaptics Incorporated 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#include <linux/input.h> 662306a36Sopenharmony_ci#include <linux/input/mt.h> 762306a36Sopenharmony_ci#include <linux/rmi.h> 862306a36Sopenharmony_ci#include "rmi_driver.h" 962306a36Sopenharmony_ci#include "rmi_2d_sensor.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cienum rmi_f12_object_type { 1262306a36Sopenharmony_ci RMI_F12_OBJECT_NONE = 0x00, 1362306a36Sopenharmony_ci RMI_F12_OBJECT_FINGER = 0x01, 1462306a36Sopenharmony_ci RMI_F12_OBJECT_STYLUS = 0x02, 1562306a36Sopenharmony_ci RMI_F12_OBJECT_PALM = 0x03, 1662306a36Sopenharmony_ci RMI_F12_OBJECT_UNCLASSIFIED = 0x04, 1762306a36Sopenharmony_ci RMI_F12_OBJECT_GLOVED_FINGER = 0x06, 1862306a36Sopenharmony_ci RMI_F12_OBJECT_NARROW_OBJECT = 0x07, 1962306a36Sopenharmony_ci RMI_F12_OBJECT_HAND_EDGE = 0x08, 2062306a36Sopenharmony_ci RMI_F12_OBJECT_COVER = 0x0A, 2162306a36Sopenharmony_ci RMI_F12_OBJECT_STYLUS_2 = 0x0B, 2262306a36Sopenharmony_ci RMI_F12_OBJECT_ERASER = 0x0C, 2362306a36Sopenharmony_ci RMI_F12_OBJECT_SMALL_OBJECT = 0x0D, 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define F12_DATA1_BYTES_PER_OBJ 8 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistruct f12_data { 2962306a36Sopenharmony_ci struct rmi_2d_sensor sensor; 3062306a36Sopenharmony_ci struct rmi_2d_sensor_platform_data sensor_pdata; 3162306a36Sopenharmony_ci bool has_dribble; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci u16 data_addr; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci struct rmi_register_descriptor query_reg_desc; 3662306a36Sopenharmony_ci struct rmi_register_descriptor control_reg_desc; 3762306a36Sopenharmony_ci struct rmi_register_descriptor data_reg_desc; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci /* F12 Data1 describes sensed objects */ 4062306a36Sopenharmony_ci const struct rmi_register_desc_item *data1; 4162306a36Sopenharmony_ci u16 data1_offset; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci /* F12 Data5 describes finger ACM */ 4462306a36Sopenharmony_ci const struct rmi_register_desc_item *data5; 4562306a36Sopenharmony_ci u16 data5_offset; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* F12 Data5 describes Pen */ 4862306a36Sopenharmony_ci const struct rmi_register_desc_item *data6; 4962306a36Sopenharmony_ci u16 data6_offset; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* F12 Data9 reports relative data */ 5362306a36Sopenharmony_ci const struct rmi_register_desc_item *data9; 5462306a36Sopenharmony_ci u16 data9_offset; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci const struct rmi_register_desc_item *data15; 5762306a36Sopenharmony_ci u16 data15_offset; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci unsigned long *abs_mask; 6062306a36Sopenharmony_ci unsigned long *rel_mask; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic int rmi_f12_read_sensor_tuning(struct f12_data *f12) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci const struct rmi_register_desc_item *item; 6662306a36Sopenharmony_ci struct rmi_2d_sensor *sensor = &f12->sensor; 6762306a36Sopenharmony_ci struct rmi_function *fn = sensor->fn; 6862306a36Sopenharmony_ci struct rmi_device *rmi_dev = fn->rmi_dev; 6962306a36Sopenharmony_ci int ret; 7062306a36Sopenharmony_ci int offset; 7162306a36Sopenharmony_ci u8 buf[15]; 7262306a36Sopenharmony_ci int pitch_x = 0; 7362306a36Sopenharmony_ci int pitch_y = 0; 7462306a36Sopenharmony_ci int rx_receivers = 0; 7562306a36Sopenharmony_ci int tx_receivers = 0; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->control_reg_desc, 8); 7862306a36Sopenharmony_ci if (!item) { 7962306a36Sopenharmony_ci dev_err(&fn->dev, 8062306a36Sopenharmony_ci "F12 does not have the sensor tuning control register\n"); 8162306a36Sopenharmony_ci return -ENODEV; 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci offset = rmi_register_desc_calc_reg_offset(&f12->control_reg_desc, 8); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (item->reg_size > sizeof(buf)) { 8762306a36Sopenharmony_ci dev_err(&fn->dev, 8862306a36Sopenharmony_ci "F12 control8 should be no bigger than %zd bytes, not: %ld\n", 8962306a36Sopenharmony_ci sizeof(buf), item->reg_size); 9062306a36Sopenharmony_ci return -ENODEV; 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr + offset, buf, 9462306a36Sopenharmony_ci item->reg_size); 9562306a36Sopenharmony_ci if (ret) 9662306a36Sopenharmony_ci return ret; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci offset = 0; 9962306a36Sopenharmony_ci if (rmi_register_desc_has_subpacket(item, 0)) { 10062306a36Sopenharmony_ci sensor->max_x = (buf[offset + 1] << 8) | buf[offset]; 10162306a36Sopenharmony_ci sensor->max_y = (buf[offset + 3] << 8) | buf[offset + 2]; 10262306a36Sopenharmony_ci offset += 4; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: max_x: %d max_y: %d\n", __func__, 10662306a36Sopenharmony_ci sensor->max_x, sensor->max_y); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci if (rmi_register_desc_has_subpacket(item, 1)) { 10962306a36Sopenharmony_ci pitch_x = (buf[offset + 1] << 8) | buf[offset]; 11062306a36Sopenharmony_ci pitch_y = (buf[offset + 3] << 8) | buf[offset + 2]; 11162306a36Sopenharmony_ci offset += 4; 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci if (rmi_register_desc_has_subpacket(item, 2)) { 11562306a36Sopenharmony_ci /* Units 1/128 sensor pitch */ 11662306a36Sopenharmony_ci rmi_dbg(RMI_DEBUG_FN, &fn->dev, 11762306a36Sopenharmony_ci "%s: Inactive Border xlo:%d xhi:%d ylo:%d yhi:%d\n", 11862306a36Sopenharmony_ci __func__, 11962306a36Sopenharmony_ci buf[offset], buf[offset + 1], 12062306a36Sopenharmony_ci buf[offset + 2], buf[offset + 3]); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci offset += 4; 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci if (rmi_register_desc_has_subpacket(item, 3)) { 12662306a36Sopenharmony_ci rx_receivers = buf[offset]; 12762306a36Sopenharmony_ci tx_receivers = buf[offset + 1]; 12862306a36Sopenharmony_ci offset += 2; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* Skip over sensor flags */ 13262306a36Sopenharmony_ci if (rmi_register_desc_has_subpacket(item, 4)) 13362306a36Sopenharmony_ci offset += 1; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci sensor->x_mm = (pitch_x * rx_receivers) >> 12; 13662306a36Sopenharmony_ci sensor->y_mm = (pitch_y * tx_receivers) >> 12; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x_mm: %d y_mm: %d\n", __func__, 13962306a36Sopenharmony_ci sensor->x_mm, sensor->y_mm); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci return 0; 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci int i; 14762306a36Sopenharmony_ci struct rmi_2d_sensor *sensor = &f12->sensor; 14862306a36Sopenharmony_ci int objects = f12->data1->num_subpackets; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci if ((f12->data1->num_subpackets * F12_DATA1_BYTES_PER_OBJ) > size) 15162306a36Sopenharmony_ci objects = size / F12_DATA1_BYTES_PER_OBJ; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci for (i = 0; i < objects; i++) { 15462306a36Sopenharmony_ci struct rmi_2d_sensor_abs_object *obj = &sensor->objs[i]; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci obj->type = RMI_2D_OBJECT_NONE; 15762306a36Sopenharmony_ci obj->mt_tool = MT_TOOL_FINGER; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci switch (data1[0]) { 16062306a36Sopenharmony_ci case RMI_F12_OBJECT_FINGER: 16162306a36Sopenharmony_ci obj->type = RMI_2D_OBJECT_FINGER; 16262306a36Sopenharmony_ci break; 16362306a36Sopenharmony_ci case RMI_F12_OBJECT_STYLUS: 16462306a36Sopenharmony_ci obj->type = RMI_2D_OBJECT_STYLUS; 16562306a36Sopenharmony_ci obj->mt_tool = MT_TOOL_PEN; 16662306a36Sopenharmony_ci break; 16762306a36Sopenharmony_ci case RMI_F12_OBJECT_PALM: 16862306a36Sopenharmony_ci obj->type = RMI_2D_OBJECT_PALM; 16962306a36Sopenharmony_ci obj->mt_tool = MT_TOOL_PALM; 17062306a36Sopenharmony_ci break; 17162306a36Sopenharmony_ci case RMI_F12_OBJECT_UNCLASSIFIED: 17262306a36Sopenharmony_ci obj->type = RMI_2D_OBJECT_UNCLASSIFIED; 17362306a36Sopenharmony_ci break; 17462306a36Sopenharmony_ci } 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci obj->x = (data1[2] << 8) | data1[1]; 17762306a36Sopenharmony_ci obj->y = (data1[4] << 8) | data1[3]; 17862306a36Sopenharmony_ci obj->z = data1[5]; 17962306a36Sopenharmony_ci obj->wx = data1[6]; 18062306a36Sopenharmony_ci obj->wy = data1[7]; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci rmi_2d_sensor_abs_process(sensor, obj, i); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci data1 += F12_DATA1_BYTES_PER_OBJ; 18562306a36Sopenharmony_ci } 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci if (sensor->kernel_tracking) 18862306a36Sopenharmony_ci input_mt_assign_slots(sensor->input, 18962306a36Sopenharmony_ci sensor->tracking_slots, 19062306a36Sopenharmony_ci sensor->tracking_pos, 19162306a36Sopenharmony_ci sensor->nbr_fingers, 19262306a36Sopenharmony_ci sensor->dmax); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci for (i = 0; i < objects; i++) 19562306a36Sopenharmony_ci rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i); 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic irqreturn_t rmi_f12_attention(int irq, void *ctx) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci int retval; 20162306a36Sopenharmony_ci struct rmi_function *fn = ctx; 20262306a36Sopenharmony_ci struct rmi_device *rmi_dev = fn->rmi_dev; 20362306a36Sopenharmony_ci struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); 20462306a36Sopenharmony_ci struct f12_data *f12 = dev_get_drvdata(&fn->dev); 20562306a36Sopenharmony_ci struct rmi_2d_sensor *sensor = &f12->sensor; 20662306a36Sopenharmony_ci int valid_bytes = sensor->pkt_size; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci if (drvdata->attn_data.data) { 20962306a36Sopenharmony_ci if (sensor->attn_size > drvdata->attn_data.size) 21062306a36Sopenharmony_ci valid_bytes = drvdata->attn_data.size; 21162306a36Sopenharmony_ci else 21262306a36Sopenharmony_ci valid_bytes = sensor->attn_size; 21362306a36Sopenharmony_ci memcpy(sensor->data_pkt, drvdata->attn_data.data, 21462306a36Sopenharmony_ci valid_bytes); 21562306a36Sopenharmony_ci drvdata->attn_data.data += valid_bytes; 21662306a36Sopenharmony_ci drvdata->attn_data.size -= valid_bytes; 21762306a36Sopenharmony_ci } else { 21862306a36Sopenharmony_ci retval = rmi_read_block(rmi_dev, f12->data_addr, 21962306a36Sopenharmony_ci sensor->data_pkt, sensor->pkt_size); 22062306a36Sopenharmony_ci if (retval < 0) { 22162306a36Sopenharmony_ci dev_err(&fn->dev, "Failed to read object data. Code: %d.\n", 22262306a36Sopenharmony_ci retval); 22362306a36Sopenharmony_ci return IRQ_RETVAL(retval); 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ci } 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (f12->data1) 22862306a36Sopenharmony_ci rmi_f12_process_objects(f12, 22962306a36Sopenharmony_ci &sensor->data_pkt[f12->data1_offset], valid_bytes); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci input_mt_sync_frame(sensor->input); 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci return IRQ_HANDLED; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic int rmi_f12_write_control_regs(struct rmi_function *fn) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci int ret; 23962306a36Sopenharmony_ci const struct rmi_register_desc_item *item; 24062306a36Sopenharmony_ci struct rmi_device *rmi_dev = fn->rmi_dev; 24162306a36Sopenharmony_ci struct f12_data *f12 = dev_get_drvdata(&fn->dev); 24262306a36Sopenharmony_ci int control_size; 24362306a36Sopenharmony_ci char buf[3]; 24462306a36Sopenharmony_ci u16 control_offset = 0; 24562306a36Sopenharmony_ci u8 subpacket_offset = 0; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci if (f12->has_dribble 24862306a36Sopenharmony_ci && (f12->sensor.dribble != RMI_REG_STATE_DEFAULT)) { 24962306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->control_reg_desc, 20); 25062306a36Sopenharmony_ci if (item) { 25162306a36Sopenharmony_ci control_offset = rmi_register_desc_calc_reg_offset( 25262306a36Sopenharmony_ci &f12->control_reg_desc, 20); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* 25562306a36Sopenharmony_ci * The byte containing the EnableDribble bit will be 25662306a36Sopenharmony_ci * in either byte 0 or byte 2 of control 20. Depending 25762306a36Sopenharmony_ci * on the existence of subpacket 0. If control 20 is 25862306a36Sopenharmony_ci * larger then 3 bytes, just read the first 3. 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci control_size = min(item->reg_size, 3UL); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr 26362306a36Sopenharmony_ci + control_offset, buf, control_size); 26462306a36Sopenharmony_ci if (ret) 26562306a36Sopenharmony_ci return ret; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci if (rmi_register_desc_has_subpacket(item, 0)) 26862306a36Sopenharmony_ci subpacket_offset += 1; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci switch (f12->sensor.dribble) { 27162306a36Sopenharmony_ci case RMI_REG_STATE_OFF: 27262306a36Sopenharmony_ci buf[subpacket_offset] &= ~BIT(2); 27362306a36Sopenharmony_ci break; 27462306a36Sopenharmony_ci case RMI_REG_STATE_ON: 27562306a36Sopenharmony_ci buf[subpacket_offset] |= BIT(2); 27662306a36Sopenharmony_ci break; 27762306a36Sopenharmony_ci case RMI_REG_STATE_DEFAULT: 27862306a36Sopenharmony_ci default: 27962306a36Sopenharmony_ci break; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci ret = rmi_write_block(rmi_dev, 28362306a36Sopenharmony_ci fn->fd.control_base_addr + control_offset, 28462306a36Sopenharmony_ci buf, control_size); 28562306a36Sopenharmony_ci if (ret) 28662306a36Sopenharmony_ci return ret; 28762306a36Sopenharmony_ci } 28862306a36Sopenharmony_ci } 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci return 0; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_cistatic int rmi_f12_config(struct rmi_function *fn) 29562306a36Sopenharmony_ci{ 29662306a36Sopenharmony_ci struct rmi_driver *drv = fn->rmi_dev->driver; 29762306a36Sopenharmony_ci struct f12_data *f12 = dev_get_drvdata(&fn->dev); 29862306a36Sopenharmony_ci struct rmi_2d_sensor *sensor; 29962306a36Sopenharmony_ci int ret; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci sensor = &f12->sensor; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci if (!sensor->report_abs) 30462306a36Sopenharmony_ci drv->clear_irq_bits(fn->rmi_dev, f12->abs_mask); 30562306a36Sopenharmony_ci else 30662306a36Sopenharmony_ci drv->set_irq_bits(fn->rmi_dev, f12->abs_mask); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci drv->clear_irq_bits(fn->rmi_dev, f12->rel_mask); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci ret = rmi_f12_write_control_regs(fn); 31162306a36Sopenharmony_ci if (ret) 31262306a36Sopenharmony_ci dev_warn(&fn->dev, 31362306a36Sopenharmony_ci "Failed to write F12 control registers: %d\n", ret); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci return 0; 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistatic int rmi_f12_probe(struct rmi_function *fn) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci struct f12_data *f12; 32162306a36Sopenharmony_ci int ret; 32262306a36Sopenharmony_ci struct rmi_device *rmi_dev = fn->rmi_dev; 32362306a36Sopenharmony_ci char buf; 32462306a36Sopenharmony_ci u16 query_addr = fn->fd.query_base_addr; 32562306a36Sopenharmony_ci const struct rmi_register_desc_item *item; 32662306a36Sopenharmony_ci struct rmi_2d_sensor *sensor; 32762306a36Sopenharmony_ci struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); 32862306a36Sopenharmony_ci struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); 32962306a36Sopenharmony_ci u16 data_offset = 0; 33062306a36Sopenharmony_ci int mask_size; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci mask_size = BITS_TO_LONGS(drvdata->irq_count) * sizeof(unsigned long); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci ret = rmi_read(fn->rmi_dev, query_addr, &buf); 33762306a36Sopenharmony_ci if (ret < 0) { 33862306a36Sopenharmony_ci dev_err(&fn->dev, "Failed to read general info register: %d\n", 33962306a36Sopenharmony_ci ret); 34062306a36Sopenharmony_ci return -ENODEV; 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci ++query_addr; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci if (!(buf & BIT(0))) { 34562306a36Sopenharmony_ci dev_err(&fn->dev, 34662306a36Sopenharmony_ci "Behavior of F12 without register descriptors is undefined.\n"); 34762306a36Sopenharmony_ci return -ENODEV; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci f12 = devm_kzalloc(&fn->dev, sizeof(struct f12_data) + mask_size * 2, 35162306a36Sopenharmony_ci GFP_KERNEL); 35262306a36Sopenharmony_ci if (!f12) 35362306a36Sopenharmony_ci return -ENOMEM; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci f12->abs_mask = (unsigned long *)((char *)f12 35662306a36Sopenharmony_ci + sizeof(struct f12_data)); 35762306a36Sopenharmony_ci f12->rel_mask = (unsigned long *)((char *)f12 35862306a36Sopenharmony_ci + sizeof(struct f12_data) + mask_size); 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci set_bit(fn->irq_pos, f12->abs_mask); 36162306a36Sopenharmony_ci set_bit(fn->irq_pos + 1, f12->rel_mask); 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci f12->has_dribble = !!(buf & BIT(3)); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci if (fn->dev.of_node) { 36662306a36Sopenharmony_ci ret = rmi_2d_sensor_of_probe(&fn->dev, &f12->sensor_pdata); 36762306a36Sopenharmony_ci if (ret) 36862306a36Sopenharmony_ci return ret; 36962306a36Sopenharmony_ci } else { 37062306a36Sopenharmony_ci f12->sensor_pdata = pdata->sensor_pdata; 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci ret = rmi_read_register_desc(rmi_dev, query_addr, 37462306a36Sopenharmony_ci &f12->query_reg_desc); 37562306a36Sopenharmony_ci if (ret) { 37662306a36Sopenharmony_ci dev_err(&fn->dev, 37762306a36Sopenharmony_ci "Failed to read the Query Register Descriptor: %d\n", 37862306a36Sopenharmony_ci ret); 37962306a36Sopenharmony_ci return ret; 38062306a36Sopenharmony_ci } 38162306a36Sopenharmony_ci query_addr += 3; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci ret = rmi_read_register_desc(rmi_dev, query_addr, 38462306a36Sopenharmony_ci &f12->control_reg_desc); 38562306a36Sopenharmony_ci if (ret) { 38662306a36Sopenharmony_ci dev_err(&fn->dev, 38762306a36Sopenharmony_ci "Failed to read the Control Register Descriptor: %d\n", 38862306a36Sopenharmony_ci ret); 38962306a36Sopenharmony_ci return ret; 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci query_addr += 3; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci ret = rmi_read_register_desc(rmi_dev, query_addr, 39462306a36Sopenharmony_ci &f12->data_reg_desc); 39562306a36Sopenharmony_ci if (ret) { 39662306a36Sopenharmony_ci dev_err(&fn->dev, 39762306a36Sopenharmony_ci "Failed to read the Data Register Descriptor: %d\n", 39862306a36Sopenharmony_ci ret); 39962306a36Sopenharmony_ci return ret; 40062306a36Sopenharmony_ci } 40162306a36Sopenharmony_ci query_addr += 3; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci sensor = &f12->sensor; 40462306a36Sopenharmony_ci sensor->fn = fn; 40562306a36Sopenharmony_ci f12->data_addr = fn->fd.data_base_addr; 40662306a36Sopenharmony_ci sensor->pkt_size = rmi_register_desc_calc_size(&f12->data_reg_desc); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci sensor->axis_align = 40962306a36Sopenharmony_ci f12->sensor_pdata.axis_align; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci sensor->x_mm = f12->sensor_pdata.x_mm; 41262306a36Sopenharmony_ci sensor->y_mm = f12->sensor_pdata.y_mm; 41362306a36Sopenharmony_ci sensor->dribble = f12->sensor_pdata.dribble; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci if (sensor->sensor_type == rmi_sensor_default) 41662306a36Sopenharmony_ci sensor->sensor_type = 41762306a36Sopenharmony_ci f12->sensor_pdata.sensor_type; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: data packet size: %d\n", __func__, 42062306a36Sopenharmony_ci sensor->pkt_size); 42162306a36Sopenharmony_ci sensor->data_pkt = devm_kzalloc(&fn->dev, sensor->pkt_size, GFP_KERNEL); 42262306a36Sopenharmony_ci if (!sensor->data_pkt) 42362306a36Sopenharmony_ci return -ENOMEM; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci dev_set_drvdata(&fn->dev, f12); 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci ret = rmi_f12_read_sensor_tuning(f12); 42862306a36Sopenharmony_ci if (ret) 42962306a36Sopenharmony_ci return ret; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci /* 43262306a36Sopenharmony_ci * Figure out what data is contained in the data registers. HID devices 43362306a36Sopenharmony_ci * may have registers defined, but their data is not reported in the 43462306a36Sopenharmony_ci * HID attention report. Registers which are not reported in the HID 43562306a36Sopenharmony_ci * attention report check to see if the device is receiving data from 43662306a36Sopenharmony_ci * HID attention reports. 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 0); 43962306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 44062306a36Sopenharmony_ci data_offset += item->reg_size; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 1); 44362306a36Sopenharmony_ci if (item) { 44462306a36Sopenharmony_ci f12->data1 = item; 44562306a36Sopenharmony_ci f12->data1_offset = data_offset; 44662306a36Sopenharmony_ci data_offset += item->reg_size; 44762306a36Sopenharmony_ci sensor->nbr_fingers = item->num_subpackets; 44862306a36Sopenharmony_ci sensor->report_abs = 1; 44962306a36Sopenharmony_ci sensor->attn_size += item->reg_size; 45062306a36Sopenharmony_ci } 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 2); 45362306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 45462306a36Sopenharmony_ci data_offset += item->reg_size; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 3); 45762306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 45862306a36Sopenharmony_ci data_offset += item->reg_size; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 4); 46162306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 46262306a36Sopenharmony_ci data_offset += item->reg_size; 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 5); 46562306a36Sopenharmony_ci if (item) { 46662306a36Sopenharmony_ci f12->data5 = item; 46762306a36Sopenharmony_ci f12->data5_offset = data_offset; 46862306a36Sopenharmony_ci data_offset += item->reg_size; 46962306a36Sopenharmony_ci sensor->attn_size += item->reg_size; 47062306a36Sopenharmony_ci } 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 6); 47362306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) { 47462306a36Sopenharmony_ci f12->data6 = item; 47562306a36Sopenharmony_ci f12->data6_offset = data_offset; 47662306a36Sopenharmony_ci data_offset += item->reg_size; 47762306a36Sopenharmony_ci } 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 7); 48062306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 48162306a36Sopenharmony_ci data_offset += item->reg_size; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 8); 48462306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 48562306a36Sopenharmony_ci data_offset += item->reg_size; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 9); 48862306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) { 48962306a36Sopenharmony_ci f12->data9 = item; 49062306a36Sopenharmony_ci f12->data9_offset = data_offset; 49162306a36Sopenharmony_ci data_offset += item->reg_size; 49262306a36Sopenharmony_ci if (!sensor->report_abs) 49362306a36Sopenharmony_ci sensor->report_rel = 1; 49462306a36Sopenharmony_ci } 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 10); 49762306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 49862306a36Sopenharmony_ci data_offset += item->reg_size; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 11); 50162306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 50262306a36Sopenharmony_ci data_offset += item->reg_size; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 12); 50562306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 50662306a36Sopenharmony_ci data_offset += item->reg_size; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 13); 50962306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 51062306a36Sopenharmony_ci data_offset += item->reg_size; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 14); 51362306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) 51462306a36Sopenharmony_ci data_offset += item->reg_size; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci item = rmi_get_register_desc_item(&f12->data_reg_desc, 15); 51762306a36Sopenharmony_ci if (item && !drvdata->attn_data.data) { 51862306a36Sopenharmony_ci f12->data15 = item; 51962306a36Sopenharmony_ci f12->data15_offset = data_offset; 52062306a36Sopenharmony_ci data_offset += item->reg_size; 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci /* allocate the in-kernel tracking buffers */ 52462306a36Sopenharmony_ci sensor->tracking_pos = devm_kcalloc(&fn->dev, 52562306a36Sopenharmony_ci sensor->nbr_fingers, sizeof(struct input_mt_pos), 52662306a36Sopenharmony_ci GFP_KERNEL); 52762306a36Sopenharmony_ci sensor->tracking_slots = devm_kcalloc(&fn->dev, 52862306a36Sopenharmony_ci sensor->nbr_fingers, sizeof(int), GFP_KERNEL); 52962306a36Sopenharmony_ci sensor->objs = devm_kcalloc(&fn->dev, 53062306a36Sopenharmony_ci sensor->nbr_fingers, 53162306a36Sopenharmony_ci sizeof(struct rmi_2d_sensor_abs_object), 53262306a36Sopenharmony_ci GFP_KERNEL); 53362306a36Sopenharmony_ci if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) 53462306a36Sopenharmony_ci return -ENOMEM; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci ret = rmi_2d_sensor_configure_input(fn, sensor); 53762306a36Sopenharmony_ci if (ret) 53862306a36Sopenharmony_ci return ret; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci return 0; 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistruct rmi_function_handler rmi_f12_handler = { 54462306a36Sopenharmony_ci .driver = { 54562306a36Sopenharmony_ci .name = "rmi4_f12", 54662306a36Sopenharmony_ci }, 54762306a36Sopenharmony_ci .func = 0x12, 54862306a36Sopenharmony_ci .probe = rmi_f12_probe, 54962306a36Sopenharmony_ci .config = rmi_f12_config, 55062306a36Sopenharmony_ci .attention = rmi_f12_attention, 55162306a36Sopenharmony_ci}; 552