Lines Matching +full:gpi +full:- +full:config
1 // SPDX-License-Identifier: GPL-2.0-only
7 * Copyright (C) 2010-2011 Analog Devices Inc.
201 #define ADP5585_MAXGPIO 11 /* 10 on the ADP5585-01, 11 on ADP5585-02 */
301 1u << (offset - ADP5585_COL_SHIFT) : 1u << offset; in adp5585_bit()
377 dev_err(&client->dev, "Read Error\n"); in adp5589_read()
391 unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); in adp5589_gpio_get_value()
392 unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); in adp5589_gpio_get_value()
394 return !!(adp5589_read(kpad->client, in adp5589_gpio_get_value()
395 kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) & in adp5589_gpio_get_value()
403 unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); in adp5589_gpio_set_value()
404 unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); in adp5589_gpio_set_value()
406 mutex_lock(&kpad->gpio_lock); in adp5589_gpio_set_value()
409 kpad->dat_out[bank] |= bit; in adp5589_gpio_set_value()
411 kpad->dat_out[bank] &= ~bit; in adp5589_gpio_set_value()
413 adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) + in adp5589_gpio_set_value()
414 bank, kpad->dat_out[bank]); in adp5589_gpio_set_value()
416 mutex_unlock(&kpad->gpio_lock); in adp5589_gpio_set_value()
422 unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); in adp5589_gpio_direction_input()
423 unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); in adp5589_gpio_direction_input()
426 mutex_lock(&kpad->gpio_lock); in adp5589_gpio_direction_input()
428 kpad->dir[bank] &= ~bit; in adp5589_gpio_direction_input()
429 ret = adp5589_write(kpad->client, in adp5589_gpio_direction_input()
430 kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank, in adp5589_gpio_direction_input()
431 kpad->dir[bank]); in adp5589_gpio_direction_input()
433 mutex_unlock(&kpad->gpio_lock); in adp5589_gpio_direction_input()
442 unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); in adp5589_gpio_direction_output()
443 unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); in adp5589_gpio_direction_output()
446 mutex_lock(&kpad->gpio_lock); in adp5589_gpio_direction_output()
448 kpad->dir[bank] |= bit; in adp5589_gpio_direction_output()
451 kpad->dat_out[bank] |= bit; in adp5589_gpio_direction_output()
453 kpad->dat_out[bank] &= ~bit; in adp5589_gpio_direction_output()
455 ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) in adp5589_gpio_direction_output()
456 + bank, kpad->dat_out[bank]); in adp5589_gpio_direction_output()
457 ret |= adp5589_write(kpad->client, in adp5589_gpio_direction_output()
458 kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank, in adp5589_gpio_direction_output()
459 kpad->dir[bank]); in adp5589_gpio_direction_output()
461 mutex_unlock(&kpad->gpio_lock); in adp5589_gpio_direction_output()
475 for (i = 0; i < kpad->var->maxgpio; i++) in adp5589_build_gpiomap()
476 if (pdata->keypad_en_mask & (1 << i)) in adp5589_build_gpiomap()
479 for (i = 0; i < kpad->gpimapsize; i++) in adp5589_build_gpiomap()
480 pin_used[kpad->gpimap[i].pin - kpad->var->gpi_pin_base] = true; in adp5589_build_gpiomap()
482 if (kpad->extend_cfg & R4_EXTEND_CFG) in adp5589_build_gpiomap()
485 if (kpad->extend_cfg & C4_EXTEND_CFG) in adp5589_build_gpiomap()
486 pin_used[kpad->var->c4_extend_cfg] = true; in adp5589_build_gpiomap()
488 if (!kpad->support_row5) in adp5589_build_gpiomap()
491 for (i = 0; i < kpad->var->maxgpio; i++) in adp5589_build_gpiomap()
493 kpad->gpiomap[n_unused++] = i; in adp5589_build_gpiomap()
500 struct device *dev = &kpad->client->dev; in adp5589_gpio_add()
502 const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; in adp5589_gpio_add()
508 kpad->gc.parent = dev; in adp5589_gpio_add()
509 kpad->gc.ngpio = adp5589_build_gpiomap(kpad, pdata); in adp5589_gpio_add()
510 if (kpad->gc.ngpio == 0) { in adp5589_gpio_add()
515 kpad->export_gpio = true; in adp5589_gpio_add()
517 kpad->gc.direction_input = adp5589_gpio_direction_input; in adp5589_gpio_add()
518 kpad->gc.direction_output = adp5589_gpio_direction_output; in adp5589_gpio_add()
519 kpad->gc.get = adp5589_gpio_get_value; in adp5589_gpio_add()
520 kpad->gc.set = adp5589_gpio_set_value; in adp5589_gpio_add()
521 kpad->gc.can_sleep = 1; in adp5589_gpio_add()
523 kpad->gc.base = gpio_data->gpio_start; in adp5589_gpio_add()
524 kpad->gc.label = kpad->client->name; in adp5589_gpio_add()
525 kpad->gc.owner = THIS_MODULE; in adp5589_gpio_add()
527 mutex_init(&kpad->gpio_lock); in adp5589_gpio_add()
529 error = gpiochip_add_data(&kpad->gc, kpad); in adp5589_gpio_add()
535 for (i = 0; i <= kpad->var->bank(kpad->var->maxgpio); i++) { in adp5589_gpio_add()
536 kpad->dat_out[i] = adp5589_read(kpad->client, kpad->var->reg( in adp5589_gpio_add()
538 kpad->dir[i] = adp5589_read(kpad->client, kpad->var->reg( in adp5589_gpio_add()
542 if (gpio_data->setup) { in adp5589_gpio_add()
543 error = gpio_data->setup(kpad->client, in adp5589_gpio_add()
544 kpad->gc.base, kpad->gc.ngpio, in adp5589_gpio_add()
545 gpio_data->context); in adp5589_gpio_add()
555 struct device *dev = &kpad->client->dev; in adp5589_gpio_remove()
557 const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; in adp5589_gpio_remove()
560 if (!kpad->export_gpio) in adp5589_gpio_remove()
563 if (gpio_data->teardown) { in adp5589_gpio_remove()
564 error = gpio_data->teardown(kpad->client, in adp5589_gpio_remove()
565 kpad->gc.base, kpad->gc.ngpio, in adp5589_gpio_remove()
566 gpio_data->context); in adp5589_gpio_remove()
571 gpiochip_remove(&kpad->gc); in adp5589_gpio_remove()
589 for (i = 0; i < kpad->gpimapsize; i++) { in adp5589_report_switches()
590 if (key_val == kpad->gpimap[i].pin) { in adp5589_report_switches()
591 input_report_switch(kpad->input, in adp5589_report_switches()
592 kpad->gpimap[i].sw_evt, in adp5589_report_switches()
604 int key = adp5589_read(kpad->client, ADP5589_5_FIFO_1 + i); in adp5589_report_events()
607 if (key_val >= kpad->var->gpi_pin_base && in adp5589_report_events()
608 key_val <= kpad->var->gpi_pin_end) { in adp5589_report_events()
611 input_report_key(kpad->input, in adp5589_report_events()
612 kpad->keycode[key_val - 1], in adp5589_report_events()
621 struct i2c_client *client = kpad->client; in adp5589_irq()
627 dev_err(&client->dev, "Event Overflow Error\n"); in adp5589_irq()
633 input_sync(kpad->input); in adp5589_irq()
646 for (i = 0; i < kpad->var->keymapsize; i++) in adp5589_get_evcode()
647 if (key == kpad->keycode[i]) in adp5589_get_evcode()
650 dev_err(&kpad->client->dev, "RESET/UNLOCK key not in keycode map\n"); in adp5589_get_evcode()
652 return -EINVAL; in adp5589_get_evcode()
657 struct i2c_client *client = kpad->client; in adp5589_setup()
659 dev_get_platdata(&client->dev); in adp5589_setup()
660 u8 (*reg) (u8) = kpad->var->reg; in adp5589_setup()
666 pdata->keypad_en_mask & kpad->var->row_mask); in adp5589_setup()
668 (pdata->keypad_en_mask >> kpad->var->col_shift) & in adp5589_setup()
669 kpad->var->col_mask); in adp5589_setup()
671 if (!kpad->is_adp5585) in adp5589_setup()
673 (pdata->keypad_en_mask >> 16) & 0xFF); in adp5589_setup()
675 if (!kpad->is_adp5585 && pdata->en_keylock) { in adp5589_setup()
677 pdata->unlock_key1); in adp5589_setup()
679 pdata->unlock_key2); in adp5589_setup()
681 pdata->unlock_timer & LTIME_MASK); in adp5589_setup()
688 for (i = 0; i < pdata->gpimapsize; i++) { in adp5589_setup()
689 unsigned short pin = pdata->gpimap[i].pin; in adp5589_setup()
691 if (pin <= kpad->var->gpi_pin_row_end) { in adp5589_setup()
692 evt_mode1 |= (1 << (pin - kpad->var->gpi_pin_row_base)); in adp5589_setup()
695 ((1 << (pin - kpad->var->gpi_pin_col_base)) & 0xFF); in adp5589_setup()
696 if (!kpad->is_adp5585) in adp5589_setup()
697 evt_mode3 |= ((1 << (pin - in adp5589_setup()
698 kpad->var->gpi_pin_col_base)) >> 8); in adp5589_setup()
702 if (pdata->gpimapsize) { in adp5589_setup()
707 if (!kpad->is_adp5585) in adp5589_setup()
713 if (pdata->pull_dis_mask & pdata->pullup_en_100k & in adp5589_setup()
714 pdata->pullup_en_300k & pdata->pulldown_en_300k) in adp5589_setup()
715 dev_warn(&client->dev, "Conflicting pull resistor config\n"); in adp5589_setup()
717 for (i = 0; i <= kpad->var->max_row_num; i++) { in adp5589_setup()
719 if (pdata->pullup_en_300k & bit) in adp5589_setup()
721 else if (pdata->pulldown_en_300k & bit) in adp5589_setup()
723 else if (pdata->pullup_en_100k & bit) in adp5589_setup()
725 else if (pdata->pull_dis_mask & bit) in adp5589_setup()
730 if (i % 4 == 3 || i == kpad->var->max_row_num) { in adp5589_setup()
737 for (i = 0; i <= kpad->var->max_col_num; i++) { in adp5589_setup()
738 unsigned val = 0, bit = 1 << (i + kpad->var->col_shift); in adp5589_setup()
739 if (pdata->pullup_en_300k & bit) in adp5589_setup()
741 else if (pdata->pulldown_en_300k & bit) in adp5589_setup()
743 else if (pdata->pullup_en_100k & bit) in adp5589_setup()
745 else if (pdata->pull_dis_mask & bit) in adp5589_setup()
750 if (i % 4 == 3 || i == kpad->var->max_col_num) { in adp5589_setup()
758 if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { in adp5589_setup()
761 pdata->reset1_key_1)); in adp5589_setup()
764 pdata->reset1_key_2)); in adp5589_setup()
767 pdata->reset1_key_3)); in adp5589_setup()
768 kpad->extend_cfg |= R4_EXTEND_CFG; in adp5589_setup()
771 if (pdata->reset2_key_1 && pdata->reset2_key_2) { in adp5589_setup()
774 pdata->reset2_key_1)); in adp5589_setup()
777 pdata->reset2_key_2)); in adp5589_setup()
778 kpad->extend_cfg |= C4_EXTEND_CFG; in adp5589_setup()
781 if (kpad->extend_cfg) { in adp5589_setup()
783 pdata->reset_cfg); in adp5589_setup()
785 kpad->extend_cfg); in adp5589_setup()
789 pdata->debounce_dis_mask & kpad->var->row_mask); in adp5589_setup()
792 (pdata->debounce_dis_mask >> kpad->var->col_shift) in adp5589_setup()
793 & kpad->var->col_mask); in adp5589_setup()
795 if (!kpad->is_adp5585) in adp5589_setup()
797 (pdata->debounce_dis_mask >> 16) & 0xFF); in adp5589_setup()
800 pdata->scan_cycle_time & PTIME_MASK); in adp5589_setup()
802 (kpad->is_adp5585 ? 0 : LOGIC2_INT) | in adp5589_setup()
804 (kpad->is_adp5585 ? 0 : LOCK_INT) | in adp5589_setup()
813 dev_err(&client->dev, "Write Error\n"); in adp5589_setup()
824 int gpi_stat1 = adp5589_read(kpad->client, in adp5589_report_switch_state()
825 kpad->var->reg(ADP5589_GPI_STATUS_A)); in adp5589_report_switch_state()
826 int gpi_stat2 = adp5589_read(kpad->client, in adp5589_report_switch_state()
827 kpad->var->reg(ADP5589_GPI_STATUS_B)); in adp5589_report_switch_state()
828 int gpi_stat3 = !kpad->is_adp5585 ? in adp5589_report_switch_state()
829 adp5589_read(kpad->client, ADP5589_GPI_STATUS_C) : 0; in adp5589_report_switch_state()
831 for (i = 0; i < kpad->gpimapsize; i++) { in adp5589_report_switch_state()
832 unsigned short pin = kpad->gpimap[i].pin; in adp5589_report_switch_state()
834 if (pin <= kpad->var->gpi_pin_row_end) { in adp5589_report_switch_state()
836 pin_loc = pin - kpad->var->gpi_pin_row_base; in adp5589_report_switch_state()
837 } else if ((pin - kpad->var->gpi_pin_col_base) < 8) { in adp5589_report_switch_state()
839 pin_loc = pin - kpad->var->gpi_pin_col_base; in adp5589_report_switch_state()
842 pin_loc = pin - kpad->var->gpi_pin_col_base - 8; in adp5589_report_switch_state()
846 dev_err(&kpad->client->dev, in adp5589_report_switch_state()
852 input_report_switch(kpad->input, in adp5589_report_switch_state()
853 kpad->gpimap[i].sw_evt, in adp5589_report_switch_state()
857 input_sync(kpad->input); in adp5589_report_switch_state()
862 struct i2c_client *client = kpad->client; in adp5589_keypad_add()
864 dev_get_platdata(&client->dev); in adp5589_keypad_add()
869 if (!((pdata->keypad_en_mask & kpad->var->row_mask) && in adp5589_keypad_add()
870 (pdata->keypad_en_mask >> kpad->var->col_shift)) || in adp5589_keypad_add()
871 !pdata->keymap) { in adp5589_keypad_add()
872 dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); in adp5589_keypad_add()
873 return -EINVAL; in adp5589_keypad_add()
876 if (pdata->keymapsize != kpad->var->keymapsize) { in adp5589_keypad_add()
877 dev_err(&client->dev, "invalid keymapsize\n"); in adp5589_keypad_add()
878 return -EINVAL; in adp5589_keypad_add()
881 if (!pdata->gpimap && pdata->gpimapsize) { in adp5589_keypad_add()
882 dev_err(&client->dev, "invalid gpimap from pdata\n"); in adp5589_keypad_add()
883 return -EINVAL; in adp5589_keypad_add()
886 if (pdata->gpimapsize > kpad->var->gpimapsize_max) { in adp5589_keypad_add()
887 dev_err(&client->dev, "invalid gpimapsize\n"); in adp5589_keypad_add()
888 return -EINVAL; in adp5589_keypad_add()
891 for (i = 0; i < pdata->gpimapsize; i++) { in adp5589_keypad_add()
892 unsigned short pin = pdata->gpimap[i].pin; in adp5589_keypad_add()
894 if (pin < kpad->var->gpi_pin_base || in adp5589_keypad_add()
895 pin > kpad->var->gpi_pin_end) { in adp5589_keypad_add()
896 dev_err(&client->dev, "invalid gpi pin data\n"); in adp5589_keypad_add()
897 return -EINVAL; in adp5589_keypad_add()
900 if ((1 << (pin - kpad->var->gpi_pin_row_base)) & in adp5589_keypad_add()
901 pdata->keypad_en_mask) { in adp5589_keypad_add()
902 dev_err(&client->dev, "invalid gpi row/col data\n"); in adp5589_keypad_add()
903 return -EINVAL; in adp5589_keypad_add()
907 if (!client->irq) { in adp5589_keypad_add()
908 dev_err(&client->dev, "no IRQ?\n"); in adp5589_keypad_add()
909 return -EINVAL; in adp5589_keypad_add()
914 return -ENOMEM; in adp5589_keypad_add()
916 kpad->input = input; in adp5589_keypad_add()
918 input->name = client->name; in adp5589_keypad_add()
919 input->phys = "adp5589-keys/input0"; in adp5589_keypad_add()
920 input->dev.parent = &client->dev; in adp5589_keypad_add()
924 input->id.bustype = BUS_I2C; in adp5589_keypad_add()
925 input->id.vendor = 0x0001; in adp5589_keypad_add()
926 input->id.product = 0x0001; in adp5589_keypad_add()
927 input->id.version = revid; in adp5589_keypad_add()
929 input->keycodesize = sizeof(kpad->keycode[0]); in adp5589_keypad_add()
930 input->keycodemax = pdata->keymapsize; in adp5589_keypad_add()
931 input->keycode = kpad->keycode; in adp5589_keypad_add()
933 memcpy(kpad->keycode, pdata->keymap, in adp5589_keypad_add()
934 pdata->keymapsize * input->keycodesize); in adp5589_keypad_add()
936 kpad->gpimap = pdata->gpimap; in adp5589_keypad_add()
937 kpad->gpimapsize = pdata->gpimapsize; in adp5589_keypad_add()
940 __set_bit(EV_KEY, input->evbit); in adp5589_keypad_add()
942 if (pdata->repeat) in adp5589_keypad_add()
943 __set_bit(EV_REP, input->evbit); in adp5589_keypad_add()
945 for (i = 0; i < input->keycodemax; i++) in adp5589_keypad_add()
946 if (kpad->keycode[i] <= KEY_MAX) in adp5589_keypad_add()
947 __set_bit(kpad->keycode[i], input->keybit); in adp5589_keypad_add()
948 __clear_bit(KEY_RESERVED, input->keybit); in adp5589_keypad_add()
950 if (kpad->gpimapsize) in adp5589_keypad_add()
951 __set_bit(EV_SW, input->evbit); in adp5589_keypad_add()
952 for (i = 0; i < kpad->gpimapsize; i++) in adp5589_keypad_add()
953 __set_bit(kpad->gpimap[i].sw_evt, input->swbit); in adp5589_keypad_add()
957 dev_err(&client->dev, "unable to register input device\n"); in adp5589_keypad_add()
961 error = request_threaded_irq(client->irq, NULL, adp5589_irq, in adp5589_keypad_add()
963 client->dev.driver->name, kpad); in adp5589_keypad_add()
965 dev_err(&client->dev, "irq %d busy?\n", client->irq); in adp5589_keypad_add()
969 device_init_wakeup(&client->dev, 1); in adp5589_keypad_add()
984 if (kpad->input) { in adp5589_keypad_remove()
985 free_irq(kpad->client->irq, kpad); in adp5589_keypad_remove()
986 input_unregister_device(kpad->input); in adp5589_keypad_remove()
995 dev_get_platdata(&client->dev); in adp5589_probe()
999 if (!i2c_check_functionality(client->adapter, in adp5589_probe()
1001 dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); in adp5589_probe()
1002 return -EIO; in adp5589_probe()
1006 dev_err(&client->dev, "no platform data?\n"); in adp5589_probe()
1007 return -EINVAL; in adp5589_probe()
1012 return -ENOMEM; in adp5589_probe()
1014 kpad->client = client; in adp5589_probe()
1016 switch (id->driver_data) { in adp5589_probe()
1018 kpad->support_row5 = true; in adp5589_probe()
1021 kpad->is_adp5585 = true; in adp5589_probe()
1022 kpad->var = &const_adp5585; in adp5589_probe()
1025 kpad->support_row5 = true; in adp5589_probe()
1026 kpad->var = &const_adp5589; in adp5589_probe()
1038 if (pdata->keymapsize) { in adp5589_probe()
1048 if (kpad->gpimapsize) in adp5589_probe()
1057 dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); in adp5589_probe()
1072 adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); in adp5589_remove()
1084 struct i2c_client *client = kpad->client; in adp5589_suspend()
1086 if (!kpad->input) in adp5589_suspend()
1089 disable_irq(client->irq); in adp5589_suspend()
1091 if (device_may_wakeup(&client->dev)) in adp5589_suspend()
1092 enable_irq_wake(client->irq); in adp5589_suspend()
1100 struct i2c_client *client = kpad->client; in adp5589_resume()
1102 if (!kpad->input) in adp5589_resume()
1105 if (device_may_wakeup(&client->dev)) in adp5589_resume()
1106 disable_irq_wake(client->irq); in adp5589_resume()
1108 enable_irq(client->irq); in adp5589_resume()
1117 {"adp5589-keys", ADP5589},
1118 {"adp5585-keys", ADP5585_01},
1119 {"adp5585-02-keys", ADP5585_02}, /* Adds ROW5 to ADP5585 */