drivers/misc/eeprom/eeprom_93xx46.c

Source file repositories/reference/linux-study-clean/drivers/misc/eeprom/eeprom_93xx46.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/eeprom/eeprom_93xx46.c
Extension
.c
Size
13558 bytes
Lines
562
Domain
Driver Families
Bucket
drivers/misc
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 eeprom_93xx46_platform_data {
	unsigned char	flags;
#define EE_ADDR8	0x01		/*  8 bit addr. cfg */
#define EE_ADDR16	0x02		/* 16 bit addr. cfg */
#define EE_READONLY	0x08		/* forbid writing */
#define EE_SIZE1K	0x10		/* 1 kb of data, that is a 93xx46 */
#define EE_SIZE2K	0x20		/* 2 kb of data, that is a 93xx56 */
#define EE_SIZE4K	0x40		/* 4 kb of data, that is a 93xx66 */

	unsigned int	quirks;
/* Single word read transfers only; no sequential read. */
#define EEPROM_93XX46_QUIRK_SINGLE_WORD_READ		(1 << 0)
/* Instructions such as EWEN are (addrlen + 2) in length. */
#define EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH		(1 << 1)
/* Add extra cycle after address during a read */
#define EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE		BIT(2)

	struct gpio_desc *select;
};

#define OP_START	0x4
#define OP_WRITE	(OP_START | 0x1)
#define OP_READ		(OP_START | 0x2)
/* The following addresses are offset for the 1K EEPROM variant in 16-bit mode */
#define ADDR_EWDS	0x00
#define ADDR_ERAL	0x20
#define ADDR_EWEN	0x30

struct eeprom_93xx46_devtype_data {
	unsigned int quirks;
	unsigned char flags;
};

static const struct eeprom_93xx46_devtype_data at93c46_data = {
	.flags = EE_SIZE1K,
};

static const struct eeprom_93xx46_devtype_data at93c56_data = {
	.flags = EE_SIZE2K,
};

static const struct eeprom_93xx46_devtype_data at93c66_data = {
	.flags = EE_SIZE4K,
};

static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = {
	.flags = EE_SIZE1K,
	.quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ |
		  EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH,
};

static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = {
	.flags = EE_SIZE1K,
	.quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE,
};

struct eeprom_93xx46_dev {
	struct spi_device *spi;
	struct eeprom_93xx46_platform_data *pdata;
	struct mutex lock;
	struct nvmem_config nvmem_config;
	struct nvmem_device *nvmem;
	int addrlen;
	int size;
};

static inline bool has_quirk_single_word_read(struct eeprom_93xx46_dev *edev)
{
	return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ;
}

static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev)
{
	return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH;
}

static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev)
{
	return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE;
}

static int eeprom_93xx46_read(void *priv, unsigned int off,
			      void *val, size_t count)
{
	struct eeprom_93xx46_dev *edev = priv;
	char *buf = val;
	int err = 0;
	int bits;

	if (unlikely(off >= edev->size))

Annotation

Implementation Notes