drivers/auxdisplay/lcd2s.c

Source file repositories/reference/linux-study-clean/drivers/auxdisplay/lcd2s.c

File Facts

System
Linux kernel
Corpus path
drivers/auxdisplay/lcd2s.c
Extension
.c
Size
8999 bytes
Lines
383
Domain
Driver Families
Bucket
drivers/auxdisplay
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 lcd2s_data {
	struct i2c_client *i2c;
	struct charlcd *charlcd;
};

static s32 lcd2s_wait_buf_free(const struct i2c_client *client, int count)
{
	s32 status;

	status = i2c_smbus_read_byte_data(client, LCD2S_CMD_READ_STATUS);
	if (status < 0)
		return status;

	while ((status & LCD2S_STATUS_BUF_MASK) < count) {
		mdelay(1);
		status = i2c_smbus_read_byte_data(client,
						  LCD2S_CMD_READ_STATUS);
		if (status < 0)
			return status;
	}
	return 0;
}

static int lcd2s_i2c_master_send(const struct i2c_client *client,
				 const char *buf, int count)
{
	s32 status;

	status = lcd2s_wait_buf_free(client, count);
	if (status < 0)
		return status;

	return i2c_master_send(client, buf, count);
}

static int lcd2s_i2c_smbus_write_byte(const struct i2c_client *client, u8 value)
{
	s32 status;

	status = lcd2s_wait_buf_free(client, 1);
	if (status < 0)
		return status;

	return i2c_smbus_write_byte(client, value);
}

static int lcd2s_print(struct charlcd *lcd, int c)
{
	struct lcd2s_data *lcd2s = lcd->drvdata;
	u8 buf[2] = { LCD2S_CMD_WRITE, c };
	int ret;

	ret = lcd2s_i2c_master_send(lcd2s->i2c, buf, sizeof(buf));
	if (ret < 0)
		return ret;
	if (ret != sizeof(buf))
		return -EIO;
	return 0;
}

static int lcd2s_gotoxy(struct charlcd *lcd, unsigned int x, unsigned int y)
{
	struct lcd2s_data *lcd2s = lcd->drvdata;
	u8 buf[3] = { LCD2S_CMD_CUR_POS, y + 1, x + 1 };
	int ret;

	ret = lcd2s_i2c_master_send(lcd2s->i2c, buf, sizeof(buf));
	if (ret < 0)
		return ret;
	if (ret != sizeof(buf))
		return -EIO;
	return 0;
}

static int lcd2s_home(struct charlcd *lcd)
{
	struct lcd2s_data *lcd2s = lcd->drvdata;

	lcd2s_i2c_smbus_write_byte(lcd2s->i2c, LCD2S_CMD_CUR_RESET);
	return 0;
}

static int lcd2s_init_display(struct charlcd *lcd)
{
	struct lcd2s_data *lcd2s = lcd->drvdata;

	/* turn everything off, but display on */
	lcd2s_i2c_smbus_write_byte(lcd2s->i2c, LCD2S_CMD_DISPLAY_ON);
	lcd2s_i2c_smbus_write_byte(lcd2s->i2c, LCD2S_CMD_BACKLIGHT_OFF);
	lcd2s_i2c_smbus_write_byte(lcd2s->i2c, LCD2S_CMD_CUR_MOVES_FWD);

Annotation

Implementation Notes