drivers: i2s: i2s_litex: Calculate offsets from DT

To support both 8-bit and 32-bit Control/Status register variants, register
offsets need to be calculated from device tree.

Updated register data in device tree to the 32-bit CSR variant.
Renamed defines to be similar to other LiteX drivers.

Changed frequencies in clock-outputs nodes, so i2s/litex sample works.

Signed-off-by: Michal Sieron <msieron@internships.antmicro.com>
This commit is contained in:
Michal Sieron 2022-05-23 15:26:36 +02:00 committed by Marti Bolivar
commit dc98691c97
3 changed files with 64 additions and 51 deletions

View file

@ -27,9 +27,9 @@ LOG_MODULE_REGISTER(i2s_litex);
*/
static void i2s_enable(uintptr_t reg)
{
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_REG_OFFSET);
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_OFFSET);
litex_write8(reg_data | I2S_ENABLE, reg + I2S_CONTROL_REG_OFFSET);
litex_write8(reg_data | I2S_ENABLE, reg + I2S_CONTROL_OFFSET);
}
/**
@ -39,9 +39,9 @@ static void i2s_enable(uintptr_t reg)
*/
static void i2s_disable(uintptr_t reg)
{
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_REG_OFFSET);
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_OFFSET);
litex_write8(reg_data & ~(I2S_ENABLE), reg + I2S_CONTROL_REG_OFFSET);
litex_write8(reg_data & ~(I2S_ENABLE), reg + I2S_CONTROL_OFFSET);
}
/**
@ -51,9 +51,9 @@ static void i2s_disable(uintptr_t reg)
*/
static void i2s_reset_fifo(uintptr_t reg)
{
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_REG_OFFSET);
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_OFFSET);
litex_write8(reg_data | I2S_FIFO_RESET, reg + I2S_CONTROL_REG_OFFSET);
litex_write8(reg_data | I2S_FIFO_RESET, reg + I2S_CONTROL_OFFSET);
}
/**
@ -66,7 +66,7 @@ static void i2s_reset_fifo(uintptr_t reg)
*/
static i2s_fmt_t i2s_get_foramt(uintptr_t reg)
{
uint8_t reg_data = litex_read32(reg + I2S_CONFIG_REG_OFFSET);
uint8_t reg_data = litex_read32(reg + I2S_CONFIG_OFFSET);
reg_data &= I2S_CONF_FORMAT_MASK;
if (reg_data == LITEX_I2S_STANDARD) {
@ -86,7 +86,7 @@ static i2s_fmt_t i2s_get_foramt(uintptr_t reg)
*/
static uint32_t i2s_get_sample_width(uintptr_t reg)
{
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_REG_OFFSET);
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_OFFSET);
reg_data &= I2S_CONF_SAMPLE_WIDTH_MASK;
return reg_data >> I2S_CONF_SAMPLE_WIDTH_OFFSET;
@ -101,7 +101,7 @@ static uint32_t i2s_get_sample_width(uintptr_t reg)
*/
static uint32_t i2s_get_audio_freq(uintptr_t reg)
{
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_REG_OFFSET);
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_OFFSET);
reg_data &= I2S_CONF_LRCK_MASK;
return reg_data >> I2S_CONF_LRCK_FREQ_OFFSET;
@ -117,9 +117,9 @@ static void i2s_irq_enable(uintptr_t reg, int irq_type)
{
__ASSERT_NO_MSG(irq_type == I2S_EV_READY || irq_type == I2S_EV_ERROR);
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_REG_OFFSET);
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_OFFSET);
litex_write8(reg_data | irq_type, reg + I2S_EV_ENABLE_REG_OFFSET);
litex_write8(reg_data | irq_type, reg + I2S_EV_ENABLE_OFFSET);
}
/**
@ -132,9 +132,9 @@ static void i2s_irq_disable(uintptr_t reg, int irq_type)
{
__ASSERT_NO_MSG(irq_type == I2S_EV_READY || irq_type == I2S_EV_ERROR);
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_REG_OFFSET);
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_OFFSET);
litex_write8(reg_data & ~(irq_type), reg + I2S_EV_ENABLE_REG_OFFSET);
litex_write8(reg_data & ~(irq_type), reg + I2S_EV_ENABLE_OFFSET);
}
/**
@ -144,9 +144,9 @@ static void i2s_irq_disable(uintptr_t reg, int irq_type)
*/
static void i2s_clear_pending_irq(uintptr_t reg)
{
uint8_t reg_data = litex_read8(reg + I2S_EV_PENDING_REG_OFFSET);
uint8_t reg_data = litex_read8(reg + I2S_EV_PENDING_OFFSET);
litex_write8(reg_data, reg + I2S_EV_PENDING_REG_OFFSET);
litex_write8(reg_data, reg + I2S_EV_PENDING_OFFSET);
}
/**
@ -323,18 +323,16 @@ static int i2s_litex_configure(const struct device *dev, enum i2s_dir dir,
struct i2s_litex_data *const dev_data = dev->data;
const struct i2s_litex_cfg *const cfg = dev->config;
struct stream *stream;
int channels_concatenated;
int channels_concatenated = litex_read8(cfg->base + I2S_STATUS_OFFSET);
int dev_audio_freq = i2s_get_audio_freq(cfg->base);
int channel_div;
if (dir == I2S_DIR_RX) {
stream = &dev_data->rx;
channels_concatenated = litex_read8(I2S_RX_STATUS_REG) &
I2S_RX_STAT_CHANNEL_CONCATENATED_MASK;
channels_concatenated &= I2S_RX_STAT_CHANNEL_CONCATENATED_MASK;
} else if (dir == I2S_DIR_TX) {
stream = &dev_data->tx;
channels_concatenated = litex_read8(I2S_TX_STATUS_REG) &
I2S_TX_STAT_CHANNEL_CONCATENATED_MASK;
channels_concatenated &= I2S_TX_STAT_CHANNEL_CONCATENATED_MASK;
} else if (dir == I2S_DIR_BOTH) {
return -ENOSYS;
} else {
@ -612,7 +610,7 @@ static const struct i2s_driver_api i2s_litex_driver_api = {
static void i2s_litex_irq_config_func_##dir(const struct device *dev); \
\
static struct i2s_litex_cfg i2s_litex_cfg_##dir = { \
.base = DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_##dir), control), \
.base = DT_REG_ADDR(DT_NODELABEL(i2s_##dir)), \
.fifo_base = \
DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_##dir), fifo), \
.fifo_depth = DT_PROP(DT_NODELABEL(i2s_##dir), fifo_depth), \

View file

@ -11,14 +11,6 @@
#include <zephyr/drivers/i2s.h>
#include <zephyr/devicetree.h>
/* i2s register offsets*/
#define I2S_EV_STATUS_REG_OFFSET 0x0
#define I2S_EV_PENDING_REG_OFFSET 0x4
#define I2S_EV_ENABLE_REG_OFFSET 0x8
#define I2S_CONTROL_REG_OFFSET 0xc
#define I2S_STATUS_REG_OFFSET 0x10
#define I2S_CONFIG_REG_OFFSET 0x20
/* i2s configuration mask*/
#define I2S_CONF_FORMAT_OFFSET 0
#define I2S_CONF_SAMPLE_WIDTH_OFFSET 2
@ -36,14 +28,6 @@
#define I2S_EV_READY (1 << 0)
#define I2S_EV_ERROR (1 << 1)
/* i2s rx*/
#define I2S_RX_BASE_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), control)
#define I2S_RX_EV_STATUS_REG (I2S_RX_BASE_ADDR + I2S_EV_STATUS_REG_OFFSET)
#define I2S_RX_EV_PENDING_REG (I2S_RX_BASE_ADDR + I2S_EV_PENDING_REG_OFFSET)
#define I2S_RX_EV_ENABLE_REG (I2S_RX_BASE_ADDR + I2S_EV_ENABLE_REG_OFFSET)
#define I2S_RX_CONTROL_REG (I2S_RX_BASE_ADDR + I2S_CONTROL_REG_OFFSET)
#define I2S_RX_STATUS_REG (I2S_RX_BASE_ADDR + I2S_STATUS_REG_OFFSET)
#define I2S_RX_CONFIG_REG (I2S_RX_BASE_ADDR + I2S_CONFIG_REG_OFFSET)
#define I2S_RX_STAT_CHANNEL_CONCATENATED_OFFSET 31
#define I2S_RX_STAT_CHANNEL_CONCATENATED_MASK \
(0x1 << I2S_RX_STAT_CHANNEL_CONCATENATED_OFFSET)
@ -52,14 +36,6 @@
#define I2S_RX_FIFO_DEPTH DT_PROP(DT_NODELABEL(i2s_rx), fifo_depth)
/* i2s tx*/
#define I2S_TX_BASE_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_tx), control)
#define I2S_TX_EV_STATUS_REG (I2S_RX_BASE_ADDR + I2S_EV_STATUS_REG_OFFSET)
#define I2S_TX_EV_PENDING_REG (I2S_TX_BASE_ADDR + I2S_EV_PENDING_REG_OFFSET)
#define I2S_TX_EV_ENABLE_REG (I2S_TX_BASE_ADDR + I2S_EV_ENABLE_REG_OFFSET)
#define I2S_TX_CONTROL_REG (I2S_TX_BASE_ADDR + I2S_CONTROL_REG_OFFSET)
#define I2S_TX_STATUS_REG (I2S_TX_BASE_ADDR + I2S_STATUS_REG_OFFSET)
#define I2S_TX_CONFIG_REG (I2S_TX_BASE_ADDR + I2S_CONFIG_REG_OFFSET)
#define I2S_TX_STAT_CHANNEL_CONCATENATED_OFFSET 24
#define I2S_TX_STAT_CHANNEL_CONCATENATED_MASK \
(0x1 << I2S_TX_STAT_CHANNEL_CONCATENATED_OFFSET)
@ -67,6 +43,21 @@
#define I2S_TX_FIFO_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_tx), fifo)
#define I2S_TX_FIFO_DEPTH DT_PROP(DT_NODELABEL(i2s_tx), fifo_depth)
/* i2s register offsets (they are the same for all i2s nodes, both rx and tx) */
#define I2S_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(i2s_rx))
#define I2S_EV_STATUS_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_status) \
- I2S_BASE_ADDR)
#define I2S_EV_PENDING_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_pending) \
- I2S_BASE_ADDR)
#define I2S_EV_ENABLE_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_enable) \
- I2S_BASE_ADDR)
#define I2S_CONTROL_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_ctl) \
- I2S_BASE_ADDR)
#define I2S_STATUS_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_stat) \
- I2S_BASE_ADDR)
#define I2S_CONFIG_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_conf) \
- I2S_BASE_ADDR)
enum litex_i2s_fmt {
LITEX_I2S_STANDARD = 1,
LITEX_I2S_LEFT_JUSTIFIED = 2,