blob: c61e0359d99b355a30de115fbfcd90f95d845e44 [file] [log] [blame]
/*
* Copyright (c) 2023 DENX Software Engineering GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef OA_TC6_CFG_H__
#define OA_TC6_CFG_H__
#include <stdint.h>
#include <stdbool.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/net/net_pkt.h>
#define MMS_REG(m, r) ((((m) & GENMASK(3, 0)) << 16) | ((r) & GENMASK(15, 0)))
/* Memory Map Sector (MMS) 0 */
#define OA_ID MMS_REG(0x0, 0x000) /* expect 0x11 */
#define OA_PHYID MMS_REG(0x0, 0x001)
#define OA_RESET MMS_REG(0x0, 0x003)
#define OA_RESET_SWRESET BIT(0)
#define OA_CONFIG0 MMS_REG(0x0, 0x004)
#define OA_CONFIG0_SYNC BIT(15)
#define OA_CONFIG0_RFA_ZARFE BIT(12)
#define OA_CONFIG0_PROTE BIT(5)
#define OA_STATUS0 MMS_REG(0x0, 0x008)
#define OA_STATUS0_RESETC BIT(6)
#define OA_STATUS1 MMS_REG(0x0, 0x009)
#define OA_BUFSTS MMS_REG(0x0, 0x00B)
#define OA_BUFSTS_TXC GENMASK(15, 8)
#define OA_BUFSTS_RCA GENMASK(7, 0)
#define OA_IMASK0 MMS_REG(0x0, 0x00C)
#define OA_IMASK0_TXPEM BIT(0)
#define OA_IMASK0_TXBOEM BIT(1)
#define OA_IMASK0_TXBUEM BIT(2)
#define OA_IMASK0_RXBOEM BIT(3)
#define OA_IMASK0_LOFEM BIT(4)
#define OA_IMASK0_HDREM BIT(5)
#define OA_IMASK1 MMS_REG(0x0, 0x00D)
#define OA_IMASK0_UV18M BIT(19)
/* OA Control header */
#define OA_CTRL_HDR_DNC BIT(31)
#define OA_CTRL_HDR_HDRB BIT(30)
#define OA_CTRL_HDR_WNR BIT(29)
#define OA_CTRL_HDR_AID BIT(28)
#define OA_CTRL_HDR_MMS GENMASK(27, 24)
#define OA_CTRL_HDR_ADDR GENMASK(23, 8)
#define OA_CTRL_HDR_LEN GENMASK(7, 1)
#define OA_CTRL_HDR_P BIT(0)
/* OA Data header */
#define OA_DATA_HDR_DNC BIT(31)
#define OA_DATA_HDR_SEQ BIT(30)
#define OA_DATA_HDR_NORX BIT(29)
#define OA_DATA_HDR_DV BIT(21)
#define OA_DATA_HDR_SV BIT(20)
#define OA_DATA_HDR_SWO GENMASK(19, 16)
#define OA_DATA_HDR_EV BIT(14)
#define OA_DATA_HDR_EBO GENMASK(13, 8)
#define OA_DATA_HDR_P BIT(0)
/* OA Data footer */
#define OA_DATA_FTR_EXST BIT(31)
#define OA_DATA_FTR_HDRB BIT(30)
#define OA_DATA_FTR_SYNC BIT(29)
#define OA_DATA_FTR_RCA GENMASK(28, 24)
#define OA_DATA_FTR_DV BIT(21)
#define OA_DATA_FTR_SV BIT(20)
#define OA_DATA_FTR_SWO GENMASK(19, 16)
#define OA_DATA_FTR_FD BIT(15)
#define OA_DATA_FTR_EV BIT(14)
#define OA_DATA_FTR_EBO GENMASK(13, 8)
#define OA_DATA_FTR_TXC GENMASK(5, 1)
#define OA_DATA_FTR_P BIT(0)
#define OA_TC6_HDR_SIZE 4
#define OA_TC6_FTR_SIZE 4
#define OA_TC6_BUF_ALLOC_TIMEOUT K_MSEC(10)
#define OA_TC6_FTR_RCA_MAX GENMASK(4, 0)
#define OA_TC6_FTR_TXC_MAX GENMASK(4, 0)
/**
* @brief OA TC6 data.
*/
struct oa_tc6 {
/** Pointer to SPI device */
const struct spi_dt_spec *spi;
/** OA data payload (chunk) size */
uint8_t cps;
/**
* Number of available chunks buffers in OA TC6 device to store
* data for transmission
*/
uint8_t txc;
/** Number of available chunks to read from OA TC6 device */
uint8_t rca;
/** Indication of pending interrupt in OA TC6 device */
bool exst;
/** Indication of OA TC6 device being ready for transmission */
bool sync;
/** Indication of protected control transmission mode */
bool protected;
/** Pointer to network buffer concatenated from received chunk */
struct net_buf *concat_buf;
};
typedef struct {
uint8_t mms;
uint8_t address;
uint16_t value;
} oa_mem_map_t;
/**
* @brief Calculate parity bit from data
*
* @param x data to calculate parity
*
* @return 0 if number of ones is odd, 1 otherwise.
*/
static inline bool oa_tc6_get_parity(const uint32_t x)
{
uint32_t y;
y = x ^ (x >> 1);
y = y ^ (y >> 2);
y = y ^ (y >> 4);
y = y ^ (y >> 8);
y = y ^ (y >> 16);
return !(y & 1);
}
/**
* @brief Read OA TC6 compliant device single register
*
* @param tc6 OA TC6 specific data
*
* @param reg register to read
* @param val pointer to variable to store read value
*
* @return 0 if read was successful, <0 otherwise.
*/
int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val);
/**
* @brief Write to OA TC6 compliant device a single register
*
* @param tc6 OA TC6 specific data
*
* @param reg register to read
* @param val data to send to device
*
* @return 0 if write was successful, <0 otherwise.
*/
int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val);
/**
* @brief Enable or disable the protected mode for control transactions
*
* @param tc6 OA TC6 specific data
*
* @param prote enable or disable protected control transactions
*
* @return 0 if operation was successful, <0 otherwise.
*/
int oa_tc6_set_protected_ctrl(struct oa_tc6 *tc6, bool prote);
/**
* @brief Send OA TC6 data chunks to the device
*
* @param tc6 OA TC6 specific data
*
* @param pkt network packet to be send
*
* @return 0 if data send was successful, <0 otherwise.
*/
int oa_tc6_send_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt);
/**
* @brief Read data chunks from OA TC6 device
*
* @param tc6 OA TC6 specific data
*
* @param pkt network packet to store received data
*
* @return 0 if read was successful, <0 otherwise.
*/
int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt);
/**
* @brief Perform SPI transfer of single chunk from/to OA TC6 device
*
* @param tc6 OA TC6 specific data
*
* @param buf_rx buffer to store read data
*
* @param buf_tx buffer with data to send
*
* @param hdr OA TC6 data transmission header value
*
* @param ftr poniter to OA TC6 data received footer
*
* @return 0 if transmission was successful, <0 otherwise.
*/
int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx,
uint32_t hdr, uint32_t *ftr);
/**
* @brief Read status from OA TC6 device
*
* @param tc6 OA TC6 specific data
*
* @param ftr poniter to OA TC6 data received footer
*
* @return 0 if successful, <0 otherwise.
*/
int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr);
/**
* @brief Read, modify and write control register from OA TC6 device
*
* @param tc6 OA TC6 specific data
*
* @param reg register to modify
*
* @param mask bit mask for modified register
*
* @param value to be stored in the register
*
* @return 0 if successful, <0 otherwise.
*/
int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg,
uint32_t mask, uint32_t val);
/**
* @brief Check the status of OA TC6 device
*
* @param tc6 OA TC6 specific data
*
* @return 0 if successful, <0 otherwise.
*/
int oa_tc6_check_status(struct oa_tc6 *tc6);
#endif /* OA_TC6_CFG_H__ */