drivers/input/misc/regulator-haptic.c

Source file repositories/reference/linux-study-clean/drivers/input/misc/regulator-haptic.c

File Facts

System
Linux kernel
Corpus path
drivers/input/misc/regulator-haptic.c
Extension
.c
Size
6363 bytes
Lines
258
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 regulator_haptic {
	struct device *dev;
	struct input_dev *input_dev;
	struct regulator *regulator;

	struct work_struct work;
	struct mutex mutex;

	bool active;
	bool suspended;

	unsigned int max_volt;
	unsigned int min_volt;
	unsigned int magnitude;
};

static int regulator_haptic_toggle(struct regulator_haptic *haptic, bool on)
{
	int error;

	if (haptic->active != on) {

		error = on ? regulator_enable(haptic->regulator) :
			     regulator_disable(haptic->regulator);
		if (error) {
			dev_err(haptic->dev,
				"failed to switch regulator %s: %d\n",
				str_on_off(on), error);
			return error;
		}

		haptic->active = on;
	}

	return 0;
}

static int regulator_haptic_set_voltage(struct regulator_haptic *haptic,
					 unsigned int magnitude)
{
	u64 volt_mag_multi;
	unsigned int intensity;
	int error;

	volt_mag_multi = (u64)(haptic->max_volt - haptic->min_volt) * magnitude;
	intensity = (unsigned int)(volt_mag_multi >> MAX_MAGNITUDE_SHIFT);

	error = regulator_set_voltage(haptic->regulator,
				      intensity + haptic->min_volt,
				      haptic->max_volt);
	if (error) {
		dev_err(haptic->dev, "cannot set regulator voltage to %d: %d\n",
			intensity + haptic->min_volt, error);
		return error;
	}

	regulator_haptic_toggle(haptic, !!magnitude);

	return 0;
}

static void regulator_haptic_work(struct work_struct *work)
{
	struct regulator_haptic *haptic = container_of(work,
					struct regulator_haptic, work);

	guard(mutex)(&haptic->mutex);

	if (!haptic->suspended)
		regulator_haptic_set_voltage(haptic, haptic->magnitude);
}

static int regulator_haptic_play_effect(struct input_dev *input, void *data,
					struct ff_effect *effect)
{
	struct regulator_haptic *haptic = input_get_drvdata(input);

	haptic->magnitude = effect->u.rumble.strong_magnitude;
	if (!haptic->magnitude)
		haptic->magnitude = effect->u.rumble.weak_magnitude;

	schedule_work(&haptic->work);

	return 0;
}

static void regulator_haptic_close(struct input_dev *input)
{
	struct regulator_haptic *haptic = input_get_drvdata(input);

Annotation

Implementation Notes