drivers/input/keyboard/adp5588-keys.c

Source file repositories/reference/linux-study-clean/drivers/input/keyboard/adp5588-keys.c

File Facts

System
Linux kernel
Corpus path
drivers/input/keyboard/adp5588-keys.c
Extension
.c
Size
24201 bytes
Lines
874
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct adp5588_kpad {
	struct i2c_client *client;
	struct input_dev *input;
	ktime_t irq_time;
	unsigned long delay;
	u32 row_shift;
	u32 rows;
	u32 cols;
	u32 unlock_keys[2];
	int nkeys_unlock;
	bool gpio_only;
	unsigned short keycode[ADP5588_KEYMAPSIZE];
	unsigned char gpiomap[ADP5588_MAXGPIO];
	struct gpio_chip gc;
	struct mutex gpio_lock;	/* Protect cached dir, dat_out */
	u8 dat_out[3];
	u8 dir[3];
	u8 int_en[3];
	u8 irq_mask[3];
	u8 pull_dis[3];
};

static int adp5588_read(struct i2c_client *client, u8 reg)
{
	int ret = i2c_smbus_read_byte_data(client, reg);

	if (ret < 0)
		dev_err(&client->dev, "Read Error\n");

	return ret;
}

static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
{
	return i2c_smbus_write_byte_data(client, reg, val);
}

static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned int off)
{
	struct adp5588_kpad *kpad = gpiochip_get_data(chip);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
	int val;

	guard(mutex)(&kpad->gpio_lock);

	if (kpad->dir[bank] & bit)
		val = kpad->dat_out[bank];
	else
		val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank);

	return !!(val & bit);
}

static int adp5588_gpio_set_value(struct gpio_chip *chip, unsigned int off,
				  int val)
{
	struct adp5588_kpad *kpad = gpiochip_get_data(chip);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);

	guard(mutex)(&kpad->gpio_lock);

	if (val)
		kpad->dat_out[bank] |= bit;
	else
		kpad->dat_out[bank] &= ~bit;

	return adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
			     kpad->dat_out[bank]);
}

static int adp5588_gpio_set_config(struct gpio_chip *chip,  unsigned int off,
				   unsigned long config)
{
	struct adp5588_kpad *kpad = gpiochip_get_data(chip);
	unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
	unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
	bool pull_disable;

	switch (pinconf_to_config_param(config)) {
	case PIN_CONFIG_BIAS_PULL_UP:
		pull_disable = false;
		break;
	case PIN_CONFIG_BIAS_DISABLE:
		pull_disable = true;
		break;
	default:
		return -ENOTSUPP;
	}

Annotation

Implementation Notes