drivers/pwm/pwm-rz-mtu3.c

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

File Facts

System
Linux kernel
Corpus path
drivers/pwm/pwm-rz-mtu3.c
Extension
.c
Size
15307 bytes
Lines
553
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 rz_mtu3_channel_io_map {
	u8 base_pwm_number;
	u8 num_channel_ios;
};

/**
 * struct rz_mtu3_pwm_channel - MTU3 pwm channel data
 *
 * @mtu: MTU3 channel data
 * @map: MTU3 pwm channel map
 */
struct rz_mtu3_pwm_channel {
	struct rz_mtu3_channel *mtu;
	const struct rz_mtu3_channel_io_map *map;
};

/**
 * struct rz_mtu3_pwm_chip - MTU3 pwm private data
 *
 * @clk: MTU3 module clock
 * @lock: Lock to prevent concurrent access for usage count
 * @rate: MTU3 clock rate
 * @user_count: MTU3 usage count
 * @enable_count: MTU3 enable count
 * @prescale: MTU3 prescale
 * @channel_data: MTU3 pwm channel data
 */

struct rz_mtu3_pwm_chip {
	struct clk *clk;
	struct mutex lock;
	unsigned long rate;
	u32 user_count[RZ_MTU3_MAX_HW_CHANNELS];
	u32 enable_count[RZ_MTU3_MAX_HW_CHANNELS];
	u8 prescale[RZ_MTU3_MAX_HW_CHANNELS];
	struct rz_mtu3_pwm_channel channel_data[RZ_MTU3_MAX_HW_CHANNELS];
};

/*
 * The MTU channels are {0..4, 6, 7} and the number of IO on MTU1
 * and MTU2 channel is 1 compared to 2 on others.
 */
static const struct rz_mtu3_channel_io_map channel_map[] = {
	{ 0, 2 }, { 2, 1 }, { 3, 1 }, { 4, 2 }, { 6, 2 }, { 8, 2 }, { 10, 2 }
};

static inline struct rz_mtu3_pwm_chip *to_rz_mtu3_pwm_chip(struct pwm_chip *chip)
{
	return pwmchip_get_drvdata(chip);
}

static void rz_mtu3_pwm_read_tgr_registers(struct rz_mtu3_pwm_channel *priv,
					   u16 reg_pv_offset, u16 *pv_val,
					   u16 reg_dc_offset, u16 *dc_val)
{
	*pv_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_pv_offset);
	*dc_val = rz_mtu3_16bit_ch_read(priv->mtu, reg_dc_offset);
}

static void rz_mtu3_pwm_write_tgr_registers(struct rz_mtu3_pwm_channel *priv,
					    u16 reg_pv_offset, u16 pv_val,
					    u16 reg_dc_offset, u16 dc_val)
{
	rz_mtu3_16bit_ch_write(priv->mtu, reg_pv_offset, pv_val);
	rz_mtu3_16bit_ch_write(priv->mtu, reg_dc_offset, dc_val);
}

static u8 rz_mtu3_pwm_calculate_prescale(struct rz_mtu3_pwm_chip *rz_mtu3,
					 u64 period_cycles)
{
	u32 prescaled_period_cycles;
	u8 prescale;

	/*
	 * Supported prescale values are 1, 4, 16 and 64.
	 * TODO: Support prescale values 2, 8, 32, 256 and 1024.
	 */
	prescaled_period_cycles = period_cycles >> 16;
	if (prescaled_period_cycles >= 16)
		prescale = 3;
	else
		prescale = (fls(prescaled_period_cycles) + 1) / 2;

	return prescale;
}

static struct rz_mtu3_pwm_channel *
rz_mtu3_get_channel(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, u32 hwpwm)
{
	struct rz_mtu3_pwm_channel *priv = rz_mtu3_pwm->channel_data;

Annotation

Implementation Notes