1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2011-12-05 Bernard the first version
9 * 2011-04-02 prife add mark_badblock and check_block
10 */
11
12 /*
13 * COPYRIGHT (C) 2012, Shanghai Real Thread
14 */
15
16 #ifndef __MTD_NAND_H__
17 #define __MTD_NAND_H__
18
19 #include <rtdevice.h>
20
21 struct rt_mtd_nand_driver_ops;
22 #define RT_MTD_NAND_DEVICE(device) ((struct rt_mtd_nand_device*)(device))
23
24 #define RT_MTD_EOK 0 /* NO error */
25 #define RT_MTD_EECC 1 /* ECC error */
26 #define RT_MTD_EBUSY 2 /* hardware busy */
27 #define RT_MTD_EIO 3 /* generic IO issue */
28 #define RT_MTD_ENOMEM 4 /* out of memory */
29 #define RT_MTD_ESRC 5 /* source issue */
30 #define RT_MTD_EECC_CORRECT 6 /* ECC error but correct */
31
32 struct rt_mtd_nand_device
33 {
34 struct rt_device parent;
35
36 rt_uint16_t page_size; /* The Page size in the flash */
37 rt_uint16_t oob_size; /* Out of bank size */
38 rt_uint16_t oob_free; /* the free area in oob that flash driver not use */
39 rt_uint16_t plane_num; /* the number of plane in the NAND Flash */
40
41 rt_uint32_t pages_per_block; /* The number of page a block */
42 rt_uint16_t block_total;
43
44 rt_uint32_t block_start; /* The start of available block*/
45 rt_uint32_t block_end; /* The end of available block */
46
47 /* operations interface */
48 const struct rt_mtd_nand_driver_ops* ops;
49 };
50
51 struct rt_mtd_nand_driver_ops
52 {
53 rt_err_t (*read_id) (struct rt_mtd_nand_device* device);
54
55 rt_err_t (*read_page)(struct rt_mtd_nand_device* device,
56 rt_off_t page,
57 rt_uint8_t* data, rt_uint32_t data_len,
58 rt_uint8_t * spare, rt_uint32_t spare_len);
59
60 rt_err_t (*write_page)(struct rt_mtd_nand_device * device,
61 rt_off_t page,
62 const rt_uint8_t * data, rt_uint32_t data_len,
63 const rt_uint8_t * spare, rt_uint32_t spare_len);
64 rt_err_t (*move_page) (struct rt_mtd_nand_device *device, rt_off_t src_page, rt_off_t dst_page);
65
66 rt_err_t (*erase_block)(struct rt_mtd_nand_device* device, rt_uint32_t block);
67 rt_err_t (*check_block)(struct rt_mtd_nand_device* device, rt_uint32_t block);
68 rt_err_t (*mark_badblock)(struct rt_mtd_nand_device* device, rt_uint32_t block);
69 };
70
71 rt_err_t rt_mtd_nand_register_device(const char* name, struct rt_mtd_nand_device* device);
72
rt_mtd_nand_read_id(struct rt_mtd_nand_device * device)73 rt_inline rt_uint32_t rt_mtd_nand_read_id(struct rt_mtd_nand_device* device)
74 {
75 return device->ops->read_id(device);
76 }
77
rt_mtd_nand_read(struct rt_mtd_nand_device * device,rt_off_t page,rt_uint8_t * data,rt_uint32_t data_len,rt_uint8_t * spare,rt_uint32_t spare_len)78 rt_inline rt_err_t rt_mtd_nand_read(
79 struct rt_mtd_nand_device* device,
80 rt_off_t page,
81 rt_uint8_t* data, rt_uint32_t data_len,
82 rt_uint8_t * spare, rt_uint32_t spare_len)
83 {
84 return device->ops->read_page(device, page, data, data_len, spare, spare_len);
85 }
86
rt_mtd_nand_write(struct rt_mtd_nand_device * device,rt_off_t page,const rt_uint8_t * data,rt_uint32_t data_len,const rt_uint8_t * spare,rt_uint32_t spare_len)87 rt_inline rt_err_t rt_mtd_nand_write(
88 struct rt_mtd_nand_device* device,
89 rt_off_t page,
90 const rt_uint8_t* data, rt_uint32_t data_len,
91 const rt_uint8_t * spare, rt_uint32_t spare_len)
92 {
93 return device->ops->write_page(device, page, data, data_len, spare, spare_len);
94 }
95
rt_mtd_nand_move_page(struct rt_mtd_nand_device * device,rt_off_t src_page,rt_off_t dst_page)96 rt_inline rt_err_t rt_mtd_nand_move_page(struct rt_mtd_nand_device* device,
97 rt_off_t src_page, rt_off_t dst_page)
98 {
99 return device->ops->move_page(device, src_page, dst_page);
100 }
101
rt_mtd_nand_erase_block(struct rt_mtd_nand_device * device,rt_uint32_t block)102 rt_inline rt_err_t rt_mtd_nand_erase_block(struct rt_mtd_nand_device* device, rt_uint32_t block)
103 {
104 return device->ops->erase_block(device, block);
105 }
106
rt_mtd_nand_check_block(struct rt_mtd_nand_device * device,rt_uint32_t block)107 rt_inline rt_err_t rt_mtd_nand_check_block(struct rt_mtd_nand_device* device, rt_uint32_t block)
108 {
109 return device->ops->check_block(device, block);
110 }
111
rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device * device,rt_uint32_t block)112 rt_inline rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device* device, rt_uint32_t block)
113 {
114 return device->ops->mark_badblock(device, block);
115 }
116
117 #endif /* MTD_NAND_H_ */
118