root/drivers/input/rmi4/rmi_f30.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rmi_f30_read_control_parameters
  2. rmi_f30_report_button
  3. rmi_f30_attention
  4. rmi_f30_config
  5. rmi_f30_set_ctrl_data
  6. rmi_f30_is_valid_button
  7. rmi_f30_map_gpios
  8. rmi_f30_initialize
  9. rmi_f30_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2012-2016 Synaptics Incorporated
   4  */
   5 
   6 #include <linux/kernel.h>
   7 #include <linux/rmi.h>
   8 #include <linux/input.h>
   9 #include <linux/slab.h>
  10 #include "rmi_driver.h"
  11 
  12 #define RMI_F30_QUERY_SIZE                      2
  13 
  14 /* Defs for Query 0 */
  15 #define RMI_F30_EXTENDED_PATTERNS               0x01
  16 #define RMI_F30_HAS_MAPPABLE_BUTTONS            BIT(1)
  17 #define RMI_F30_HAS_LED                         BIT(2)
  18 #define RMI_F30_HAS_GPIO                        BIT(3)
  19 #define RMI_F30_HAS_HAPTIC                      BIT(4)
  20 #define RMI_F30_HAS_GPIO_DRV_CTL                BIT(5)
  21 #define RMI_F30_HAS_MECH_MOUSE_BTNS             BIT(6)
  22 
  23 /* Defs for Query 1 */
  24 #define RMI_F30_GPIO_LED_COUNT                  0x1F
  25 
  26 /* Defs for Control Registers */
  27 #define RMI_F30_CTRL_1_GPIO_DEBOUNCE            0x01
  28 #define RMI_F30_CTRL_1_HALT                     BIT(4)
  29 #define RMI_F30_CTRL_1_HALTED                   BIT(5)
  30 #define RMI_F30_CTRL_10_NUM_MECH_MOUSE_BTNS     0x03
  31 
  32 #define RMI_F30_CTRL_MAX_REGS           32
  33 #define RMI_F30_CTRL_MAX_BYTES          DIV_ROUND_UP(RMI_F30_CTRL_MAX_REGS, 8)
  34 #define RMI_F30_CTRL_MAX_REG_BLOCKS     11
  35 
  36 #define RMI_F30_CTRL_REGS_MAX_SIZE (RMI_F30_CTRL_MAX_BYTES              \
  37                                         + 1                             \
  38                                         + RMI_F30_CTRL_MAX_BYTES        \
  39                                         + RMI_F30_CTRL_MAX_BYTES        \
  40                                         + RMI_F30_CTRL_MAX_BYTES        \
  41                                         + 6                             \
  42                                         + RMI_F30_CTRL_MAX_REGS         \
  43                                         + RMI_F30_CTRL_MAX_REGS         \
  44                                         + RMI_F30_CTRL_MAX_BYTES        \
  45                                         + 1                             \
  46                                         + 1)
  47 
  48 #define TRACKSTICK_RANGE_START          3
  49 #define TRACKSTICK_RANGE_END            6
  50 
  51 struct rmi_f30_ctrl_data {
  52         int address;
  53         int length;
  54         u8 *regs;
  55 };
  56 
  57 struct f30_data {
  58         /* Query Data */
  59         bool has_extended_pattern;
  60         bool has_mappable_buttons;
  61         bool has_led;
  62         bool has_gpio;
  63         bool has_haptic;
  64         bool has_gpio_driver_control;
  65         bool has_mech_mouse_btns;
  66         u8 gpioled_count;
  67 
  68         u8 register_count;
  69 
  70         /* Control Register Data */
  71         struct rmi_f30_ctrl_data ctrl[RMI_F30_CTRL_MAX_REG_BLOCKS];
  72         u8 ctrl_regs[RMI_F30_CTRL_REGS_MAX_SIZE];
  73         u32 ctrl_regs_size;
  74 
  75         u8 data_regs[RMI_F30_CTRL_MAX_BYTES];
  76         u16 *gpioled_key_map;
  77 
  78         struct input_dev *input;
  79 
  80         struct rmi_function *f03;
  81         bool trackstick_buttons;
  82 };
  83 
  84 static int rmi_f30_read_control_parameters(struct rmi_function *fn,
  85                                                 struct f30_data *f30)
  86 {
  87         int error;
  88 
  89         error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
  90                                f30->ctrl_regs, f30->ctrl_regs_size);
  91         if (error) {
  92                 dev_err(&fn->dev,
  93                         "%s: Could not read control registers at 0x%x: %d\n",
  94                         __func__, fn->fd.control_base_addr, error);
  95                 return error;
  96         }
  97 
  98         return 0;
  99 }
 100 
 101 static void rmi_f30_report_button(struct rmi_function *fn,
 102                                   struct f30_data *f30, unsigned int button)
 103 {
 104         unsigned int reg_num = button >> 3;
 105         unsigned int bit_num = button & 0x07;
 106         u16 key_code = f30->gpioled_key_map[button];
 107         bool key_down = !(f30->data_regs[reg_num] & BIT(bit_num));
 108 
 109         if (f30->trackstick_buttons &&
 110             button >= TRACKSTICK_RANGE_START &&
 111             button <= TRACKSTICK_RANGE_END) {
 112                 rmi_f03_overwrite_button(f30->f03, key_code, key_down);
 113         } else {
 114                 rmi_dbg(RMI_DEBUG_FN, &fn->dev,
 115                         "%s: call input report key (0x%04x) value (0x%02x)",
 116                         __func__, key_code, key_down);
 117 
 118                 input_report_key(f30->input, key_code, key_down);
 119         }
 120 }
 121 
 122 static irqreturn_t rmi_f30_attention(int irq, void *ctx)
 123 {
 124         struct rmi_function *fn = ctx;
 125         struct f30_data *f30 = dev_get_drvdata(&fn->dev);
 126         struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
 127         int error;
 128         int i;
 129 
 130         /* Read the gpi led data. */
 131         if (drvdata->attn_data.data) {
 132                 if (drvdata->attn_data.size < f30->register_count) {
 133                         dev_warn(&fn->dev,
 134                                  "F30 interrupted, but data is missing\n");
 135                         return IRQ_HANDLED;
 136                 }
 137                 memcpy(f30->data_regs, drvdata->attn_data.data,
 138                         f30->register_count);
 139                 drvdata->attn_data.data += f30->register_count;
 140                 drvdata->attn_data.size -= f30->register_count;
 141         } else {
 142                 error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
 143                                        f30->data_regs, f30->register_count);
 144                 if (error) {
 145                         dev_err(&fn->dev,
 146                                 "%s: Failed to read F30 data registers: %d\n",
 147                                 __func__, error);
 148                         return IRQ_RETVAL(error);
 149                 }
 150         }
 151 
 152         if (f30->has_gpio) {
 153                 for (i = 0; i < f30->gpioled_count; i++)
 154                         if (f30->gpioled_key_map[i] != KEY_RESERVED)
 155                                 rmi_f30_report_button(fn, f30, i);
 156                 if (f30->trackstick_buttons)
 157                         rmi_f03_commit_buttons(f30->f03);
 158         }
 159 
 160         return IRQ_HANDLED;
 161 }
 162 
 163 static int rmi_f30_config(struct rmi_function *fn)
 164 {
 165         struct f30_data *f30 = dev_get_drvdata(&fn->dev);
 166         struct rmi_driver *drv = fn->rmi_dev->driver;
 167         const struct rmi_device_platform_data *pdata =
 168                                 rmi_get_platform_data(fn->rmi_dev);
 169         int error;
 170 
 171         /* can happen if f30_data.disable is set */
 172         if (!f30)
 173                 return 0;
 174 
 175         if (pdata->f30_data.trackstick_buttons) {
 176                 /* Try [re-]establish link to F03. */
 177                 f30->f03 = rmi_find_function(fn->rmi_dev, 0x03);
 178                 f30->trackstick_buttons = f30->f03 != NULL;
 179         }
 180 
 181         if (pdata->f30_data.disable) {
 182                 drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask);
 183         } else {
 184                 /* Write Control Register values back to device */
 185                 error = rmi_write_block(fn->rmi_dev, fn->fd.control_base_addr,
 186                                         f30->ctrl_regs, f30->ctrl_regs_size);
 187                 if (error) {
 188                         dev_err(&fn->dev,
 189                                 "%s: Could not write control registers at 0x%x: %d\n",
 190                                 __func__, fn->fd.control_base_addr, error);
 191                         return error;
 192                 }
 193 
 194                 drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
 195         }
 196 
 197         return 0;
 198 }
 199 
 200 static void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
 201                                   int *ctrl_addr, int len, u8 **reg)
 202 {
 203         ctrl->address = *ctrl_addr;
 204         ctrl->length = len;
 205         ctrl->regs = *reg;
 206         *ctrl_addr += len;
 207         *reg += len;
 208 }
 209 
 210 static bool rmi_f30_is_valid_button(int button, struct rmi_f30_ctrl_data *ctrl)
 211 {
 212         int byte_position = button >> 3;
 213         int bit_position = button & 0x07;
 214 
 215         /*
 216          * ctrl2 -> dir == 0 -> input mode
 217          * ctrl3 -> data == 1 -> actual button
 218          */
 219         return !(ctrl[2].regs[byte_position] & BIT(bit_position)) &&
 220                 (ctrl[3].regs[byte_position] & BIT(bit_position));
 221 }
 222 
 223 static int rmi_f30_map_gpios(struct rmi_function *fn,
 224                              struct f30_data *f30)
 225 {
 226         const struct rmi_device_platform_data *pdata =
 227                                         rmi_get_platform_data(fn->rmi_dev);
 228         struct input_dev *input = f30->input;
 229         unsigned int button = BTN_LEFT;
 230         unsigned int trackstick_button = BTN_LEFT;
 231         bool button_mapped = false;
 232         int i;
 233         int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END);
 234 
 235         f30->gpioled_key_map = devm_kcalloc(&fn->dev,
 236                                             button_count,
 237                                             sizeof(f30->gpioled_key_map[0]),
 238                                             GFP_KERNEL);
 239         if (!f30->gpioled_key_map) {
 240                 dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n");
 241                 return -ENOMEM;
 242         }
 243 
 244         for (i = 0; i < button_count; i++) {
 245                 if (!rmi_f30_is_valid_button(i, f30->ctrl))
 246                         continue;
 247 
 248                 if (pdata->f30_data.trackstick_buttons &&
 249                     i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) {
 250                         f30->gpioled_key_map[i] = trackstick_button++;
 251                 } else if (!pdata->f30_data.buttonpad || !button_mapped) {
 252                         f30->gpioled_key_map[i] = button;
 253                         input_set_capability(input, EV_KEY, button++);
 254                         button_mapped = true;
 255                 }
 256         }
 257 
 258         input->keycode = f30->gpioled_key_map;
 259         input->keycodesize = sizeof(f30->gpioled_key_map[0]);
 260         input->keycodemax = f30->gpioled_count;
 261 
 262         /*
 263          * Buttonpad could be also inferred from f30->has_mech_mouse_btns,
 264          * but I am not sure, so use only the pdata info and the number of
 265          * mapped buttons.
 266          */
 267         if (pdata->f30_data.buttonpad || (button - BTN_LEFT == 1))
 268                 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 269 
 270         return 0;
 271 }
 272 
 273 static int rmi_f30_initialize(struct rmi_function *fn, struct f30_data *f30)
 274 {
 275         u8 *ctrl_reg = f30->ctrl_regs;
 276         int control_address = fn->fd.control_base_addr;
 277         u8 buf[RMI_F30_QUERY_SIZE];
 278         int error;
 279 
 280         error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
 281                                buf, RMI_F30_QUERY_SIZE);
 282         if (error) {
 283                 dev_err(&fn->dev, "Failed to read query register\n");
 284                 return error;
 285         }
 286 
 287         f30->has_extended_pattern = buf[0] & RMI_F30_EXTENDED_PATTERNS;
 288         f30->has_mappable_buttons = buf[0] & RMI_F30_HAS_MAPPABLE_BUTTONS;
 289         f30->has_led = buf[0] & RMI_F30_HAS_LED;
 290         f30->has_gpio = buf[0] & RMI_F30_HAS_GPIO;
 291         f30->has_haptic = buf[0] & RMI_F30_HAS_HAPTIC;
 292         f30->has_gpio_driver_control = buf[0] & RMI_F30_HAS_GPIO_DRV_CTL;
 293         f30->has_mech_mouse_btns = buf[0] & RMI_F30_HAS_MECH_MOUSE_BTNS;
 294         f30->gpioled_count = buf[1] & RMI_F30_GPIO_LED_COUNT;
 295 
 296         f30->register_count = DIV_ROUND_UP(f30->gpioled_count, 8);
 297 
 298         if (f30->has_gpio && f30->has_led)
 299                 rmi_f30_set_ctrl_data(&f30->ctrl[0], &control_address,
 300                                       f30->register_count, &ctrl_reg);
 301 
 302         rmi_f30_set_ctrl_data(&f30->ctrl[1], &control_address,
 303                               sizeof(u8), &ctrl_reg);
 304 
 305         if (f30->has_gpio) {
 306                 rmi_f30_set_ctrl_data(&f30->ctrl[2], &control_address,
 307                                       f30->register_count, &ctrl_reg);
 308 
 309                 rmi_f30_set_ctrl_data(&f30->ctrl[3], &control_address,
 310                                       f30->register_count, &ctrl_reg);
 311         }
 312 
 313         if (f30->has_led) {
 314                 rmi_f30_set_ctrl_data(&f30->ctrl[4], &control_address,
 315                                       f30->register_count, &ctrl_reg);
 316 
 317                 rmi_f30_set_ctrl_data(&f30->ctrl[5], &control_address,
 318                                       f30->has_extended_pattern ? 6 : 2,
 319                                       &ctrl_reg);
 320         }
 321 
 322         if (f30->has_led || f30->has_gpio_driver_control) {
 323                 /* control 6 uses a byte per gpio/led */
 324                 rmi_f30_set_ctrl_data(&f30->ctrl[6], &control_address,
 325                                       f30->gpioled_count, &ctrl_reg);
 326         }
 327 
 328         if (f30->has_mappable_buttons) {
 329                 /* control 7 uses a byte per gpio/led */
 330                 rmi_f30_set_ctrl_data(&f30->ctrl[7], &control_address,
 331                                       f30->gpioled_count, &ctrl_reg);
 332         }
 333 
 334         if (f30->has_haptic) {
 335                 rmi_f30_set_ctrl_data(&f30->ctrl[8], &control_address,
 336                                       f30->register_count, &ctrl_reg);
 337 
 338                 rmi_f30_set_ctrl_data(&f30->ctrl[9], &control_address,
 339                                       sizeof(u8), &ctrl_reg);
 340         }
 341 
 342         if (f30->has_mech_mouse_btns)
 343                 rmi_f30_set_ctrl_data(&f30->ctrl[10], &control_address,
 344                                       sizeof(u8), &ctrl_reg);
 345 
 346         f30->ctrl_regs_size = ctrl_reg -
 347                                 f30->ctrl_regs ?: RMI_F30_CTRL_REGS_MAX_SIZE;
 348 
 349         error = rmi_f30_read_control_parameters(fn, f30);
 350         if (error) {
 351                 dev_err(&fn->dev,
 352                         "Failed to initialize F30 control params: %d\n",
 353                         error);
 354                 return error;
 355         }
 356 
 357         if (f30->has_gpio) {
 358                 error = rmi_f30_map_gpios(fn, f30);
 359                 if (error)
 360                         return error;
 361         }
 362 
 363         return 0;
 364 }
 365 
 366 static int rmi_f30_probe(struct rmi_function *fn)
 367 {
 368         struct rmi_device *rmi_dev = fn->rmi_dev;
 369         const struct rmi_device_platform_data *pdata =
 370                                         rmi_get_platform_data(rmi_dev);
 371         struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
 372         struct f30_data *f30;
 373         int error;
 374 
 375         if (pdata->f30_data.disable)
 376                 return 0;
 377 
 378         if (!drv_data->input) {
 379                 dev_info(&fn->dev, "F30: no input device found, ignoring\n");
 380                 return -ENXIO;
 381         }
 382 
 383         f30 = devm_kzalloc(&fn->dev, sizeof(*f30), GFP_KERNEL);
 384         if (!f30)
 385                 return -ENOMEM;
 386 
 387         f30->input = drv_data->input;
 388 
 389         error = rmi_f30_initialize(fn, f30);
 390         if (error)
 391                 return error;
 392 
 393         dev_set_drvdata(&fn->dev, f30);
 394         return 0;
 395 }
 396 
 397 struct rmi_function_handler rmi_f30_handler = {
 398         .driver = {
 399                 .name = "rmi4_f30",
 400         },
 401         .func = 0x30,
 402         .probe = rmi_f30_probe,
 403         .config = rmi_f30_config,
 404         .attention = rmi_f30_attention,
 405 };

/* [<][>][^][v][top][bottom][index][help] */