drivers/regulator/rpi-panel-attiny-regulator.c

Source file repositories/reference/linux-study-clean/drivers/regulator/rpi-panel-attiny-regulator.c

File Facts

System
Linux kernel
Corpus path
drivers/regulator/rpi-panel-attiny-regulator.c
Extension
.c
Size
9175 bytes
Lines
385
Domain
Driver Families
Bucket
drivers/regulator
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 gpio_signal_mappings {
	unsigned int reg;
	unsigned int mask;
};

static const struct gpio_signal_mappings mappings[NUM_GPIO] = {
	[RST_BRIDGE_N] = { REG_PORTC, PC_RST_BRIDGE_N | PC_RST_LCD_N  },
	[RST_TP_N] = { REG_PORTC, PC_RST_TP_N },
};

struct attiny_lcd {
	/* lock to serialise overall accesses to the Atmel */
	struct mutex	lock;
	struct regmap	*regmap;
	bool gpio_states[NUM_GPIO];
	u8 port_states[3];

	struct gpio_chip gc;
};

static const struct regmap_config attiny_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.disable_locking = 1,
	.max_register = REG_WRITE_DATA_L,
	.cache_type = REGCACHE_MAPLE,
};

static int attiny_set_port_state(struct attiny_lcd *state, int reg, u8 val)
{
	state->port_states[reg - REG_PORTA] = val;
	return regmap_write(state->regmap, reg, val);
};

static u8 attiny_get_port_state(struct attiny_lcd *state, int reg)
{
	return state->port_states[reg - REG_PORTA];
};

static int attiny_lcd_power_enable(struct regulator_dev *rdev)
{
	struct attiny_lcd *state = rdev_get_drvdata(rdev);

	guard(mutex)(&state->lock);

	/* Ensure bridge, and tp stay in reset */
	attiny_set_port_state(state, REG_PORTC, 0);
	usleep_range(5000, 10000);

	/* Default to the same orientation as the closed source
	 * firmware used for the panel.  Runtime rotation
	 * configuration will be supported using VC4's plane
	 * orientation bits.
	 */
	attiny_set_port_state(state, REG_PORTA, PA_LCD_LR);
	usleep_range(5000, 10000);
	/* Main regulator on, and power to the panel (LCD_VCC_N) */
	attiny_set_port_state(state, REG_PORTB, PB_LCD_MAIN);
	usleep_range(5000, 10000);
	/* Bring controllers out of reset */
	attiny_set_port_state(state, REG_PORTC, PC_LED_EN);

	msleep(80);

	return 0;
}

static int attiny_lcd_power_disable(struct regulator_dev *rdev)
{
	struct attiny_lcd *state = rdev_get_drvdata(rdev);

	guard(mutex)(&state->lock);

	regmap_write(rdev->regmap, REG_PWM, 0);
	usleep_range(5000, 10000);

	attiny_set_port_state(state, REG_PORTA, 0);
	usleep_range(5000, 10000);
	attiny_set_port_state(state, REG_PORTB, PB_LCD_VCC_N);
	usleep_range(5000, 10000);
	attiny_set_port_state(state, REG_PORTC, 0);
	msleep(30);

	return 0;
}

static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev)
{
	struct attiny_lcd *state = rdev_get_drvdata(rdev);
	unsigned int data;

Annotation

Implementation Notes