drivers/pwm/pwm-stmpe.c

Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-stmpe.c

File Facts

System
Linux kernel
Corpus path
drivers/pwm/pwm-stmpe.c
Extension
.c
Size
8384 bytes
Lines
359
Domain
Driver Families
Bucket
drivers/pwm
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 stmpe_pwm {
	struct stmpe *stmpe;
	u8 last_duty;
};

static inline struct stmpe_pwm *to_stmpe_pwm(struct pwm_chip *chip)
{
	return pwmchip_get_drvdata(chip);
}

static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
	u8 value;
	int ret;

	ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);
	if (ret < 0) {
		dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n",
			pwm->hwpwm);
		return ret;
	}

	value = ret | BIT(pwm->hwpwm);

	ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
	if (ret) {
		dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n",
			pwm->hwpwm);
		return ret;
	}

	return 0;
}

static int stmpe_24xx_pwm_disable(struct pwm_chip *chip,
				  struct pwm_device *pwm)
{
	struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
	u8 value;
	int ret;

	ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);
	if (ret < 0) {
		dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n",
			pwm->hwpwm);
		return ret;
	}

	value = ret & ~BIT(pwm->hwpwm);

	ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
	if (ret)
		dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n",
			pwm->hwpwm);
	return ret;
}

/* STMPE 24xx PWM instructions */
#define SMAX		0x007f
#define SMIN		0x00ff
#define GTS		0x0000
#define LOAD		BIT(14) /* Only available on 2403 */
#define RAMPUP		0x0000
#define RAMPDOWN	BIT(7)
#define PRESCALE_512	BIT(14)
#define STEPTIME_1	BIT(8)
#define BRANCH		(BIT(15) | BIT(13))

static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
				 int duty_ns, int period_ns)
{
	struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
	unsigned int i, pin;
	u16 program[3] = {
		SMAX,
		GTS,
		GTS,
	};
	u8 offset;
	int ret;

	/* Make sure we are disabled */
	if (pwm_is_enabled(pwm)) {
		ret = stmpe_24xx_pwm_disable(chip, pwm);
		if (ret)
			return ret;
	} else {
		/* Connect the PWM to the pin */
		pin = pwm->hwpwm;

Annotation

Implementation Notes