175406Sache// Copyright 2018 The Fuchsia Authors. All rights reserved.
275406Sache// Use of this source code is governed by a BSD-style license that can be
3136644Sache// found in the LICENSE file.
475406Sache
575406Sache#pragma once
675406Sache
775406Sache#include <assert.h>
875406Sache#include <stdint.h>
975406Sache
1075406Sache#include <zircon/compiler.h>
1175406Sache#include <zircon/listnode.h>
1275406Sache
1375406Sache#include <ddk/protocol/nand.h>
1475406Sache
1575406Sache__BEGIN_CDECLS;
1675406Sache
1775406Sachetypedef struct raw_nand_protocol_ops {
1875406Sache    // Read one nand page with hwecc.
1975406Sache    zx_status_t (*read_page_hwecc)(void* ctx, void *data, void *oob,
2075406Sache                                   uint32_t nandpage, int *ecc_correct);
2175406Sache    // Write one nand page with hwecc.
2275406Sache    zx_status_t (*write_page_hwecc)(void* ctx, const void* data, const void* oob,
2375406Sache                                    uint32_t nandpage);
2475406Sache    // Erase nand block.
2575406Sache    zx_status_t (*erase_block)(void* ctx, uint32_t nandpage);
2675406Sache    zx_status_t (*get_nand_info)(void *ctx, struct nand_info *info);
2775406Sache    // Send ONFI command down to controller.
2875406Sache    void (*cmd_ctrl)(void *ctx, int32_t cmd, uint32_t ctrl);
2975406Sache    // Read byte (used to read status as well as other info, such as ID).
3075406Sache    uint8_t (*read_byte)(void *ctx);
3175406Sache} raw_nand_protocol_ops_t;
3275406Sache
3375406Sachetypedef struct raw_nand_protocol {
3475406Sache    raw_nand_protocol_ops_t *ops;
3575406Sache    void *ctx;
3675406Sache} raw_nand_protocol_t;
3775406Sache
3875406Sachestatic inline zx_status_t raw_nand_read_page_hwecc(raw_nand_protocol_t *raw_nand,
3975406Sache                                                   void *data, void *oob,
4075406Sache                                                   uint32_t nand_page,
4175406Sache                                                   int *ecc_correct)
4275406Sache{
4375406Sache    return raw_nand->ops->read_page_hwecc(raw_nand->ctx, data, oob, nand_page,
4475406Sache                                         ecc_correct);
4575406Sache}
4675406Sache
4775406Sachestatic inline zx_status_t raw_nand_write_page_hwecc(raw_nand_protocol_t* raw_nand,
48119610Sache                                                    const void* data, const void* oob,
4975406Sache                                                    uint32_t nand_page)
5075406Sache{
51119610Sache    return raw_nand->ops->write_page_hwecc(raw_nand->ctx, data, oob, nand_page);
52119610Sache}
5375406Sache
54119610Sachestatic inline zx_status_t raw_nand_erase_block(raw_nand_protocol_t *raw_nand,
55119610Sache                                               uint32_t nand_page)
5675406Sache{
57119610Sache    return raw_nand->ops->erase_block(raw_nand->ctx, nand_page);
5875406Sache}
59119610Sache
6075406Sachestatic inline zx_status_t raw_nand_get_info(raw_nand_protocol_t *raw_nand,
6175406Sache                                            struct nand_info *info)
62119610Sache{
6375406Sache    return raw_nand->ops->get_nand_info(raw_nand->ctx, info);
6475406Sache}
65119610Sache
6675406Sachestatic inline void raw_nand_cmd_ctrl(raw_nand_protocol_t *raw_nand,
6775406Sache                                     int32_t cmd, uint32_t ctrl)
6875406Sache{
6975406Sache    raw_nand->ops->cmd_ctrl(raw_nand->ctx, cmd, ctrl);
70119610Sache}
7175406Sache
7275406Sachestatic inline uint8_t raw_nand_read_byte(raw_nand_protocol_t *raw_nand)
73119610Sache{
7475406Sache    return raw_nand->ops->read_byte(raw_nand->ctx);
75119610Sache}
76119610Sache
7775406Sache__END_CDECLS;
78119610Sache
79119610Sache