cregit-Linux how code gets into the kernel

Release 4.7 include/linux/mtd/spi-nor.h

/*
 * Copyright (C) 2014 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#ifndef __LINUX_MTD_SPI_NOR_H

#define __LINUX_MTD_SPI_NOR_H

#include <linux/bitops.h>
#include <linux/mtd/cfi.h>
#include <linux/mtd/mtd.h>

/*
 * Manufacturer IDs
 *
 * The first byte returned from the flash after sending opcode SPINOR_OP_RDID.
 * Sometimes these are the same as CFI IDs, but sometimes they aren't.
 */

#define SNOR_MFR_ATMEL		CFI_MFR_ATMEL

#define SNOR_MFR_GIGADEVICE	0xc8

#define SNOR_MFR_INTEL		CFI_MFR_INTEL

#define SNOR_MFR_MICRON		CFI_MFR_ST 
/* ST Micro <--> Micron */

#define SNOR_MFR_MACRONIX	CFI_MFR_MACRONIX

#define SNOR_MFR_SPANSION	CFI_MFR_AMD

#define SNOR_MFR_SST		CFI_MFR_SST

#define SNOR_MFR_WINBOND	0xef 
/* Also used by some Spansion */

/*
 * Note on opcode nomenclature: some opcodes have a format like
 * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
 * of I/O lines used for the opcode, address, and data (respectively). The
 * FUNCTION has an optional suffix of '4', to represent an opcode which
 * requires a 4-byte (32-bit) address.
 */

/* Flash opcodes. */

#define SPINOR_OP_WREN		0x06	
/* Write enable */

#define SPINOR_OP_RDSR		0x05	
/* Read status register */

#define SPINOR_OP_WRSR		0x01	
/* Write status register 1 byte */

#define SPINOR_OP_READ		0x03	
/* Read data bytes (low frequency) */

#define SPINOR_OP_READ_FAST	0x0b	
/* Read data bytes (high frequency) */

#define SPINOR_OP_READ_1_1_2	0x3b	
/* Read data bytes (Dual SPI) */

#define SPINOR_OP_READ_1_1_4	0x6b	
/* Read data bytes (Quad SPI) */

#define SPINOR_OP_PP		0x02	
/* Page program (up to 256 bytes) */

#define SPINOR_OP_BE_4K		0x20	
/* Erase 4KiB block */

#define SPINOR_OP_BE_4K_PMC	0xd7	
/* Erase 4KiB block on PMC chips */

#define SPINOR_OP_BE_32K	0x52	
/* Erase 32KiB block */

#define SPINOR_OP_CHIP_ERASE	0xc7	
/* Erase whole flash chip */

#define SPINOR_OP_SE		0xd8	
/* Sector erase (usually 64KiB) */

#define SPINOR_OP_RDID		0x9f	
/* Read JEDEC ID */

#define SPINOR_OP_RDCR		0x35	
/* Read configuration register */

#define SPINOR_OP_RDFSR		0x70	
/* Read flag status register */

/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */

#define SPINOR_OP_READ4		0x13	
/* Read data bytes (low frequency) */

#define SPINOR_OP_READ4_FAST	0x0c	
/* Read data bytes (high frequency) */

#define SPINOR_OP_READ4_1_1_2	0x3c	
/* Read data bytes (Dual SPI) */

#define SPINOR_OP_READ4_1_1_4	0x6c	
/* Read data bytes (Quad SPI) */

#define SPINOR_OP_PP_4B		0x12	
/* Page program (up to 256 bytes) */

#define SPINOR_OP_SE_4B		0xdc	
/* Sector erase (usually 64KiB) */

/* Used for SST flashes only. */

#define SPINOR_OP_BP		0x02	
/* Byte program */

#define SPINOR_OP_WRDI		0x04	
/* Write disable */

#define SPINOR_OP_AAI_WP	0xad	
/* Auto address increment word program */

/* Used for Macronix and Winbond flashes. */

#define SPINOR_OP_EN4B		0xb7	
/* Enter 4-byte mode */

#define SPINOR_OP_EX4B		0xe9	
/* Exit 4-byte mode */

/* Used for Spansion flashes only. */

#define SPINOR_OP_BRWR		0x17	
/* Bank register write */

/* Used for Micron flashes only. */

#define SPINOR_OP_RD_EVCR      0x65    
/* Read EVCR register */

#define SPINOR_OP_WD_EVCR      0x61    
/* Write EVCR register */

/* Status Register bits. */

#define SR_WIP			BIT(0)	
/* Write in progress */

#define SR_WEL			BIT(1)	
/* Write enable latch */
/* meaning of other SR_* bits may differ between vendors */

#define SR_BP0			BIT(2)	
/* Block protect 0 */

#define SR_BP1			BIT(3)	
/* Block protect 1 */

#define SR_BP2			BIT(4)	
/* Block protect 2 */

#define SR_TB			BIT(5)	
/* Top/Bottom protect */

#define SR_SRWD			BIT(7)	
/* SR write protect */


#define SR_QUAD_EN_MX		BIT(6)	
/* Macronix Quad I/O */

/* Enhanced Volatile Configuration Register bits */

#define EVCR_QUAD_EN_MICRON	BIT(7)	
/* Micron Quad I/O */

/* Flag Status Register bits */

#define FSR_READY		BIT(7)

/* Configuration Register bits. */

#define CR_QUAD_EN_SPAN		BIT(1)	
/* Spansion Quad I/O */


enum read_mode {
	
SPI_NOR_NORMAL = 0,
	
SPI_NOR_FAST,
	
SPI_NOR_DUAL,
	
SPI_NOR_QUAD,
};


#define SPI_NOR_MAX_CMD_SIZE	8

enum spi_nor_ops {
	
SPI_NOR_OPS_READ = 0,
	
SPI_NOR_OPS_WRITE,
	
SPI_NOR_OPS_ERASE,
	
SPI_NOR_OPS_LOCK,
	
SPI_NOR_OPS_UNLOCK,
};


enum spi_nor_option_flags {
	
SNOR_F_USE_FSR		= BIT(0),
	
SNOR_F_HAS_SR_TB	= BIT(1),
};

/**
 * struct spi_nor - Structure for defining a the SPI NOR layer
 * @mtd:                point to a mtd_info structure
 * @lock:               the lock for the read/write/erase/lock/unlock operations
 * @dev:                point to a spi device, or a spi nor controller device.
 * @page_size:          the page size of the SPI NOR
 * @addr_width:         number of address bytes
 * @erase_opcode:       the opcode for erasing a sector
 * @read_opcode:        the read opcode
 * @read_dummy:         the dummy needed by the read operation
 * @program_opcode:     the program opcode
 * @flash_read:         the mode of the read
 * @sst_write_second:   used by the SST write operation
 * @flags:              flag options for the current SPI-NOR (SNOR_F_*)
 * @cmd_buf:            used by the write_reg
 * @prepare:            [OPTIONAL] do some preparations for the
 *                      read/write/erase/lock/unlock operations
 * @unprepare:          [OPTIONAL] do some post work after the
 *                      read/write/erase/lock/unlock operations
 * @read_reg:           [DRIVER-SPECIFIC] read out the register
 * @write_reg:          [DRIVER-SPECIFIC] write data to the register
 * @read:               [DRIVER-SPECIFIC] read data from the SPI NOR
 * @write:              [DRIVER-SPECIFIC] write data to the SPI NOR
 * @erase:              [DRIVER-SPECIFIC] erase a sector of the SPI NOR
 *                      at the offset @offs; if not provided by the driver,
 *                      spi-nor will send the erase opcode via write_reg()
 * @flash_lock:         [FLASH-SPECIFIC] lock a region of the SPI NOR
 * @flash_unlock:       [FLASH-SPECIFIC] unlock a region of the SPI NOR
 * @flash_is_locked:    [FLASH-SPECIFIC] check if a region of the SPI NOR is
 *                      completely locked
 * @priv:               the private data
 */

struct spi_nor {
	
struct mtd_info		mtd;
	
struct mutex		lock;
	
struct device		*dev;
	
u32			page_size;
	
u8			addr_width;
	
u8			erase_opcode;
	
u8			read_opcode;
	
u8			read_dummy;
	
u8			program_opcode;
	
enum read_mode		flash_read;
	
bool			sst_write_second;
	
u32			flags;
	
u8			cmd_buf[SPI_NOR_MAX_CMD_SIZE];

	
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
	
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
	
int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
	
int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);

	
int (*read)(struct spi_nor *nor, loff_t from,
			size_t len, size_t *retlen, u_char *read_buf);
	
void (*write)(struct spi_nor *nor, loff_t to,
			size_t len, size_t *retlen, const u_char *write_buf);
	
int (*erase)(struct spi_nor *nor, loff_t offs);

	
int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
	
int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
	
int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);

	
void *priv;
};


static inline void spi_nor_set_flash_node(struct spi_nor *nor, struct device_node *np) { mtd_set_of_node(&nor->mtd, np); }

Contributors

PersonTokensPropCommitsCommitProp
brian norrisbrian norris27100.00%2100.00%
Total27100.00%2100.00%


static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) { return mtd_get_of_node(&nor->mtd); }

Contributors

PersonTokensPropCommitsCommitProp
brian norrisbrian norris23100.00%2100.00%
Total23100.00%2100.00%

/** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure * @name: the chip type name * @mode: the read mode supported by the driver * * The drivers can use this fuction to scan the SPI NOR. * In the scanning, it will try to get all the necessary information to * fill the mtd_info{} and the spi_nor{}. * * The chip type name can be provided through the @name parameter. * * Return: 0 for success, others for failure. */ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode); #endif

Overall Contributors

PersonTokensPropCommitsCommitProp
huang shijiehuang shijie40462.64%418.18%
brian norrisbrian norris21032.56%1463.64%
bean huobean huo162.48%14.55%
graham mooregraham moore91.40%14.55%
ben hutchingsben hutchings30.47%14.55%
rafal mileckirafal milecki30.47%14.55%
Total645100.00%22100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}